///|
fn deno_core_resources_op_name() -> String {
"__mizchi_v8_deno_resources__"
}
///|
fn deno_core_close_op_name() -> String {
"__mizchi_v8_deno_close__"
}
///|
fn deno_core_try_close_op_name() -> String {
"__mizchi_v8_deno_try_close__"
}
///|
fn deno_core_sleep_op_name() -> String {
"__mizchi_v8_deno_sleep__"
}
///|
fn deno_core_resource_exists_op_name() -> String {
"__mizchi_v8_deno_resource_exists__"
}
///|
fn deno_core_sleep_resource_create_op_name() -> String {
"__mizchi_v8_deno_sleep_resource_create__"
}
///|
fn deno_core_timeout_resource_create_op_name() -> String {
"__mizchi_v8_deno_timeout_resource_create__"
}
///|
fn deno_core_interval_resource_create_op_name() -> String {
"__mizchi_v8_deno_interval_resource_create__"
}
///|
fn deno_core_promise_resource_create_op_name() -> String {
"__mizchi_v8_deno_promise_resource_create__"
}
///|
fn deno_core_ref_resource_op_name() -> String {
"__mizchi_v8_deno_ref_resource__"
}
///|
fn deno_core_unref_resource_op_name() -> String {
"__mizchi_v8_deno_unref_resource__"
}
///|
fn parse_deno_delay_ms(payload_json : String) -> Result[Int, String] {
let delay = parse_resource_rid(payload_json)
guard delay is Ok(_) else { return Err(delay.unwrap_err()) }
if delay.unwrap() <= 0 {
Ok(0)
} else {
Ok(delay.unwrap())
}
}
///|
fn json_int(value : Int) -> String {
Json::number(value.to_double(), repr=value.to_string()).stringify()
}
///|
fn json_bool(value : Bool) -> String {
Json::boolean(value).stringify()
}
///|
fn add_deno_named_resource_json(
runtime : Runtime,
name : String,
) -> Result[String, String] {
let rid = runtime_add_resource_entry(runtime, name, None, true)
guard rid is Ok(_) else { return Err(rid.unwrap_err().to_string()) }
Ok(json_int(rid.unwrap()))
}
///|
fn install_deno_core_runtime_compat(runtime : Runtime) -> Result[Unit, V8Error] {
let registered_resources = runtime.register_sync_json_result_callback(
deno_core_resources_op_name(),
_payload => {
let resources_json = runtime_resource_list_json(runtime)
guard resources_json is Ok(_) else {
return Err(resources_json.unwrap_err().to_string())
}
Ok(resources_json.unwrap())
},
)
guard registered_resources is Ok(_) else {
return Err(registered_resources.unwrap_err())
}
let registered_close = runtime.register_sync_json_result_callback(
deno_core_close_op_name(),
payload_json => {
let rid = parse_resource_rid(payload_json)
guard rid is Ok(_) else { return Err(rid.unwrap_err()) }
let closed = runtime.close_resource(rid.unwrap())
guard closed is Ok(_) else { return Err(closed.unwrap_err().to_string()) }
Ok("null")
},
)
guard registered_close is Ok(_) else {
return Err(registered_close.unwrap_err())
}
let registered_try_close = runtime.register_sync_json_result_callback(
deno_core_try_close_op_name(),
payload_json => {
let rid = parse_resource_rid(payload_json)
guard rid is Ok(_) else { return Err(rid.unwrap_err()) }
let closed = runtime.try_close_resource(rid.unwrap())
guard closed is Ok(_) else { return Err(closed.unwrap_err().to_string()) }
Ok(Json::boolean(closed.unwrap()).stringify())
},
)
guard registered_try_close is Ok(_) else {
return Err(registered_try_close.unwrap_err())
}
let registered_sleep = runtime.register_async_json_task_result_callback(
deno_core_sleep_op_name(),
payload_json => {
let delay = parse_deno_delay_ms(payload_json)
guard delay is Ok(_) else { return Err(delay.unwrap_err()) }
if delay.unwrap() == 0 {
@async.pause()
} else {
@async.sleep(delay.unwrap())
}
Ok("null")
},
)
guard registered_sleep is Ok(_) else {
return Err(registered_sleep.unwrap_err())
}
let registered_resource_exists = runtime.register_sync_json_result_callback(
deno_core_resource_exists_op_name(),
payload_json => {
let rid = parse_resource_rid(payload_json)
guard rid is Ok(_) else { return Err(rid.unwrap_err()) }
let exists = runtime_resource_exists(runtime, rid.unwrap())
guard exists is Ok(_) else { return Err(exists.unwrap_err().to_string()) }
Ok(json_bool(exists.unwrap()))
},
)
guard registered_resource_exists is Ok(_) else {
return Err(registered_resource_exists.unwrap_err())
}
let registered_sleep_resource = runtime.register_sync_json_result_callback(
deno_core_sleep_resource_create_op_name(),
_payload => add_deno_named_resource_json(runtime, "sleep"),
)
guard registered_sleep_resource is Ok(_) else {
return Err(registered_sleep_resource.unwrap_err())
}
let registered_timeout_resource = runtime.register_sync_json_result_callback(
deno_core_timeout_resource_create_op_name(),
_payload => add_deno_named_resource_json(runtime, "timeout"),
)
guard registered_timeout_resource is Ok(_) else {
return Err(registered_timeout_resource.unwrap_err())
}
let registered_interval_resource = runtime.register_sync_json_result_callback(
deno_core_interval_resource_create_op_name(),
_payload => add_deno_named_resource_json(runtime, "interval"),
)
guard registered_interval_resource is Ok(_) else {
return Err(registered_interval_resource.unwrap_err())
}
let registered_promise_resource = runtime.register_sync_json_result_callback(
deno_core_promise_resource_create_op_name(),
_payload => add_deno_named_resource_json(runtime, "promise"),
)
guard registered_promise_resource is Ok(_) else {
return Err(registered_promise_resource.unwrap_err())
}
let registered_ref_resource = runtime.register_sync_json_result_callback(
deno_core_ref_resource_op_name(),
payload_json => {
let rid = parse_resource_rid(payload_json)
guard rid is Ok(_) else { return Err(rid.unwrap_err()) }
let changed = runtime.ref_resource(rid.unwrap())
guard changed is Ok(_) else {
return Err(changed.unwrap_err().to_string())
}
Ok(json_bool(changed.unwrap()))
},
)
guard registered_ref_resource is Ok(_) else {
return Err(registered_ref_resource.unwrap_err())
}
let registered_unref_resource = runtime.register_sync_json_result_callback(
deno_core_unref_resource_op_name(),
payload_json => {
let rid = parse_resource_rid(payload_json)
guard rid is Ok(_) else { return Err(rid.unwrap_err()) }
let changed = runtime.unref_resource(rid.unwrap())
guard changed is Ok(_) else {
return Err(changed.unwrap_err().to_string())
}
Ok(json_bool(changed.unwrap()))
},
)
guard registered_unref_resource is Ok(_) else {
return Err(registered_unref_resource.unwrap_err())
}
Ok(())
}
///|
fn deno_core_compat_source() -> String {
"(function(){ " +
"const root = globalThis; " +
"const deno = root.Deno ?? (root.Deno = {}); " +
"const toDelay = function(value){ const number = Number(value ?? 0); if (!Number.isFinite(number) || number <= 0) return 0; return Math.trunc(number); }; " +
"const encode = typeof TextEncoder === 'function' ? function(value){ return new TextEncoder().encode(String(value)); } : function(value){ const text = String(value); const out = new Uint8Array(text.length); for (let i = 0; i < text.length; i += 1) out[i] = text.charCodeAt(i) & 255; return out; }; " +
"const asBytes = function(value){ if (value instanceof Uint8Array) return value; if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength); if (value instanceof ArrayBuffer) return new Uint8Array(value); return new Uint8Array(0); }; " +
"const decode = typeof TextDecoder === 'function' ? function(value){ return new TextDecoder().decode(asBytes(value)); } : function(value){ const bytes = asBytes(value); let out = ''; for (let i = 0; i < bytes.length; i += 1) out += String.fromCharCode(bytes[i]); return out; }; " +
"if (!Array.isArray(deno.args)) deno.args = []; " +
"if (typeof deno.build !== 'object' || deno.build === null) deno.build = { arch: 'unknown', os: 'unknown', vendor: 'unknown', target: 'unknown' }; " +
"if (typeof deno.version !== 'object' || deno.version === null) deno.version = { deno: '0.0.0-mizchi-v8', v8: '" +
version() +
"', typescript: 'unknown' }; " +
"if (typeof deno.pid !== 'number') deno.pid = 0; " +
"if (typeof deno.ppid !== 'number') deno.ppid = 0; " +
"if (typeof deno.noColor !== 'boolean') deno.noColor = false; " +
"if (typeof deno.exitCode !== 'number') deno.exitCode = 0; " +
"if (typeof deno.cwd !== 'function') deno.cwd = function(){ return '/'; }; " +
"if (typeof deno.execPath !== 'function') deno.execPath = function(){ return '/mizchi-v8/deno'; }; " +
"if (typeof deno.inspect !== 'function') deno.inspect = function(value, _options){ try { const inspected = JSON.stringify(value); return inspected === undefined ? String(value) : inspected; } catch (_) { return String(value); } }; " +
"const core = deno.core ?? (deno.core = {}); " +
"if (typeof core.opSync !== 'function') core.opSync = function(name, payload){ return MoonBit.opSync(name, payload); }; " +
"const promiseRidKey = '__mizchi_v8_resource_rid__'; " +
"const createManagedResource = function(kind){ switch (kind) { case 'sleep': return MoonBit.opSync('" +
deno_core_sleep_resource_create_op_name() +
"', null); case 'timeout': return MoonBit.opSync('" +
deno_core_timeout_resource_create_op_name() +
"', null); case 'interval': return MoonBit.opSync('" +
deno_core_interval_resource_create_op_name() +
"', null); default: return MoonBit.opSync('" +
deno_core_promise_resource_create_op_name() +
"', null); } }; " +
"const getPromiseRid = function(promise){ if ((typeof promise !== 'object' && typeof promise !== 'function') || promise === null) return undefined; const rid = promise[promiseRidKey]; return typeof rid === 'number' && Number.isFinite(rid) ? rid : undefined; }; " +
"const attachPromiseRid = function(promise, rid){ if ((typeof promise !== 'object' && typeof promise !== 'function') || promise === null) return promise; try { Object.defineProperty(promise, promiseRidKey, { value: rid, writable: true, configurable: true }); } catch (_) { promise[promiseRidKey] = rid; } Promise.resolve(promise).finally(function(){ core.tryClose(rid); }); return promise; }; " +
"const ensurePromiseResource = function(promise, kind){ const existing = getPromiseRid(promise); if (existing !== undefined) return existing; const rid = createManagedResource(kind); attachPromiseRid(promise, rid); return rid; }; " +
"const setPromiseRefState = function(promise, isRef){ const rid = ensurePromiseResource(promise, 'promise'); MoonBit.opSync(isRef ? '" +
deno_core_ref_resource_op_name() +
"' : '" +
deno_core_unref_resource_op_name() +
"', rid); return promise; }; " +
"const timers = root.__mizchi_v8_timers ?? (root.__mizchi_v8_timers = new Map()); " +
"const resourceExists = function(rid){ return MoonBit.opSync('" +
deno_core_resource_exists_op_name() +
"', rid); }; " +
"const closeResourceByRid = function(rid, throwOnMissing){ const id = Number(rid); timers.delete(id); if (throwOnMissing) { MoonBit.opSync('" +
deno_core_close_op_name() +
"', id); return; } return MoonBit.opSync('" +
deno_core_try_close_op_name() +
"', id); }; " +
"const scheduleTimer = function(id){ const timer = timers.get(id); if (!timer) return; MoonBit.opAsync('" +
deno_core_sleep_op_name() +
"', timer.delay).then(function(){ const current = timers.get(id); if (!current) return; if (!resourceExists(id)) { timers.delete(id); return; } try { current.callback(...current.args); } finally { if (!current.repeat) { core.tryClose(id); return; } if (timers.has(id) && resourceExists(id)) scheduleTimer(id); } }); }; " +
"if (typeof core.opAsync !== 'function') core.opAsync = function(name, payload){ return attachPromiseRid(MoonBit.opAsync(name, payload), createManagedResource('promise')); }; " +
"if (typeof core.opSyncBytes !== 'function') core.opSyncBytes = function(name, payload){ return MoonBit.opSyncBytes(name, payload); }; " +
"if (typeof core.opAsyncBytes !== 'function') core.opAsyncBytes = function(name, payload){ return attachPromiseRid(MoonBit.opAsyncBytes(name, payload), createManagedResource('promise')); }; " +
"if (typeof core.encode !== 'function') core.encode = encode; " +
"if (typeof core.decode !== 'function') core.decode = decode; " +
"if (typeof core.resources !== 'function') core.resources = function(){ return MoonBit.opSync('" +
deno_core_resources_op_name() +
"', null); }; " +
"if (typeof core.close !== 'function') core.close = function(rid){ closeResourceByRid(rid, true); }; " +
"if (typeof core.tryClose !== 'function') core.tryClose = function(rid){ return closeResourceByRid(rid, false); }; " +
"if (typeof deno.sleep !== 'function') deno.sleep = function(delay){ const rid = createManagedResource('sleep'); return attachPromiseRid(MoonBit.opAsync('" +
deno_core_sleep_op_name() +
"', toDelay(delay)).then(function(){ return undefined; }), rid); }; " +
"if (typeof root.setTimeout !== 'function') root.setTimeout = function(callback, delay, ...args){ const id = createManagedResource('timeout'); timers.set(id, { callback, args, delay: toDelay(delay), repeat: false }); scheduleTimer(id); return id; }; " +
"if (typeof root.clearTimeout !== 'function') root.clearTimeout = function(id){ closeResourceByRid(id, false); }; " +
"if (typeof root.setInterval !== 'function') root.setInterval = function(callback, delay, ...args){ const id = createManagedResource('interval'); timers.set(id, { callback, args, delay: toDelay(delay), repeat: true }); scheduleTimer(id); return id; }; " +
"if (typeof root.clearInterval !== 'function') root.clearInterval = function(id){ closeResourceByRid(id, false); }; " +
"if (typeof core.refOpPromise !== 'function') core.refOpPromise = function(promise){ return setPromiseRefState(promise, true); }; " +
"if (typeof core.unrefOpPromise !== 'function') core.unrefOpPromise = function(promise){ return setPromiseRefState(promise, false); }; " +
"if (typeof core.print !== 'function') core.print = function(message, is_err){ if (typeof console !== 'object' || console === null) return; const text = String(message); if (is_err && typeof console.error === 'function') { console.error(text); return; } if (typeof console.log === 'function') console.log(text); }; " +
"if (typeof core.ops !== 'object' || core.ops === null) core.ops = new Proxy({}, { get(_target, key) { return typeof key === 'string' ? key : undefined; } }); " +
"if (typeof core.opsBytes !== 'object' || core.opsBytes === null) core.opsBytes = new Proxy({}, { get(_target, key) { return typeof key === 'string' ? key : undefined; } }); " +
"return 'ok'; " +
"})()"
}
///|
pub fn Runtime::install_deno_core_compat(
self : Runtime,
) -> Result[Unit, V8Error] {
if runtime_has_deno_core_compat(self) {
Ok(())
} else {
let registered = install_deno_core_runtime_compat(self)
guard registered is Ok(_) else { return Err(registered.unwrap_err()) }
let installed = install_compat_source(
self,
"file:///compat/deno_core.js",
deno_core_compat_source(),
)
guard installed is Ok(_) else { return Err(installed.unwrap_err()) }
runtime_mark_deno_core_compat(self)
Ok(())
}
}
///|
pub fn RuntimeBuilder::with_deno_core_compat(
self : RuntimeBuilder,
) -> RuntimeBuilder {
self.state.val.with_deno_core_compat = true
apply_runtime_builder_compat(self, deno_core_compat_source())
}
///|
pub fn SnapshotBuilder::with_deno_core_compat(
self : SnapshotBuilder,
) -> SnapshotBuilder {
self.state.val.with_deno_core_compat = true
apply_snapshot_builder_compat(self, deno_core_compat_source())
}