Skip to content

Commit

Permalink
Rectify diverged:
Browse files Browse the repository at this point in the history
- jm/ext-ts-guest-new
- scale 34
- staging
  • Loading branch information
dphilla committed Jan 19, 2024
2 parents b0c5457 + f0e29d3 commit 5f4b9a3
Show file tree
Hide file tree
Showing 123 changed files with 108,711 additions and 738 deletions.
2 changes: 1 addition & 1 deletion compile/typescript/builder/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ path = "main.rs"

[dependencies]
scale_signature_interfaces = "0.1.7"
quickjs-wasm-sys = "1.1.0"
quickjs-wasm-sys = { path = "../quickjs-wasm-sys" }
once_cell = "1.4.0"
polyglot_rs = "1.1.3"
anyhow = "1.0.75"
Expand Down
27 changes: 26 additions & 1 deletion compile/typescript/builder/interpreter/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use polyglot_rs::Encoder;
use quickjs_wasm_sys::{
ext_js_undefined, size_t as JS_size_t, size_t, JSCFunctionData, JSContext, JSValue,
JS_DefinePropertyValueStr, JS_FreeCString, JS_NewCFunctionData, JS_ThrowInternalError,
JS_ToCStringLen2, JS_PROP_C_W_E,
JS_ToCStringLen2, JS_PROP_C_W_E, JS_TAG_UNDEFINED, JS_GetPropertyStr, JS_IsError, JS_GetException,
};
use std::error::Error;
use std::ffi::CString;
Expand Down Expand Up @@ -123,3 +123,28 @@ pub unsafe fn to_exception(ctx: *mut JSContext, e: JSValue) -> Result<String, an
let anyhow_error: anyhow::Result<&str> = std::str::from_utf8(buffer).map_err(Into::into);
anyhow_error.map(|s| s.to_string())
}

pub unsafe fn error(ctx: *mut JSContext, during: &str) -> String {
let e = JS_GetException(ctx);
let exception =
to_exception(ctx, e).expect(format!("getting exception during {during} failed").as_str());

let mut stack = None;
let is_error = JS_IsError(ctx, e) != 0;
if is_error {
let cstring_key = CString::new("stack")
.expect(format!("getting new CString for JS stack during {during} failed").as_str());
let raw = JS_GetPropertyStr(ctx, e, cstring_key.as_ptr());
if (raw >> 32) as i32 != JS_TAG_UNDEFINED {
stack.replace(to_exception(ctx, raw));
}
}
let mut err = format!("exception from js runtime during {during}: {exception}");
if let Some(Ok(stack)) = stack {
if stack.len() > 0 {
err.push_str(&format!("\nstack:\n{stack}"));
}
}

return err;
}
44 changes: 42 additions & 2 deletions compile/typescript/builder/interpreter/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
*/

pub mod helpers;
pub mod time;

use once_cell::sync::OnceCell;
use quickjs_wasm_sys::{
ext_js_undefined, JSContext, JSRuntime, JSValue, JS_BigIntToUint64, JS_NewBigUint64, JS_Call,
JS_DefinePropertyValueStr, JS_Eval, JS_GetArrayBuffer, JS_GetException, JS_GetGlobalObject,
JS_GetPropertyStr, JS_GetPropertyUint32, JS_IsError, JS_NewContext, JS_NewInt32_Ext,
JS_NewObject, JS_NewRuntime, JS_NewUint32_Ext, JS_EVAL_TYPE_GLOBAL, JS_PROP_C_W_E,
JS_TAG_EXCEPTION, JS_TAG_UNDEFINED,
JS_TAG_EXCEPTION, JS_TAG_UNDEFINED, JS_ExecutePendingJob, JS_TAG_OBJECT,
JS_GetPromiseResult,
JS_GetPromiseState, JSPromiseStateEnum_JS_PROMISE_FULFILLED, JSPromiseStateEnum_JS_PROMISE_REJECTED
};

use std::ffi::CString;
Expand All @@ -34,6 +37,7 @@ use std::str;
use flate2::read::GzDecoder;

static mut JS_INITIALIZED: bool = false;
static mut JS_RUNTIME: OnceCell<*mut JSRuntime> = OnceCell::new();
static mut JS_CONTEXT: OnceCell<*mut JSContext> = OnceCell::new();

static mut ENTRY_EXPORTS: OnceCell<JSValue> = OnceCell::new();
Expand Down Expand Up @@ -102,6 +106,8 @@ fn initialize_runtime() {
JS_PROP_C_W_E as i32,
);

time::install(context);

helpers::set_callback(
context,
global,
Expand Down Expand Up @@ -231,6 +237,7 @@ fn initialize_runtime() {
ENTRY_EXT_RESIZE.set(ext_resize_fn).unwrap();

ENTRY_EXPORTS.set(exports).unwrap();
JS_RUNTIME.set(runtime).unwrap();
JS_CONTEXT.set(context).unwrap();
JS_INITIALIZED = true;
}
Expand Down Expand Up @@ -335,19 +342,52 @@ pub extern "C" fn initialize() -> u64 {
#[no_mangle]
pub extern "C" fn run() -> u64 {
unsafe {
let runtime = JS_RUNTIME.get().unwrap();
let context = JS_CONTEXT.get().unwrap();
let exports = ENTRY_EXPORTS.get().unwrap();
let runfn = ENTRY_RUN.get().unwrap();

let args: Vec<JSValue> = Vec::new();
let ret = JS_Call(
let mut ret = JS_Call(
*context,
*runfn,
*exports,
args.len() as i32,
args.as_slice().as_ptr() as *mut JSValue,
);

// If it returned a promise, wait for it... If not, we just process the ret value as is.
if (ret >> 32) as i32 == JS_TAG_OBJECT {
let mut ctx = *context;
loop {
let pstate = JS_GetPromiseState(*context, ret);

if pstate==JSPromiseStateEnum_JS_PROMISE_FULFILLED {
break;
} else if pstate==JSPromiseStateEnum_JS_PROMISE_REJECTED {
// We don't need anything else here. The promise value should be an exception.
break;
}

// Run any timers while we wait for the promise to complete
time::run_pending_jobs(*runtime, *context);

// Run any pending quickjs jobs
match { JS_ExecutePendingJob(*runtime, &mut ctx) } {
0 => (),
1 => (),
_ => {
let err = helpers::error(ctx, "main");
panic!("{}", err);
}
}
}

// The promise has resolved/rejected. Now get the value returned by the promise.
ret = JS_GetPromiseResult(*context, ret);
}

// Process the return value...
if (ret >> 32) as i32 == JS_TAG_EXCEPTION {
let e = JS_GetException(*context);
let exception =
Expand Down
Loading

0 comments on commit 5f4b9a3

Please sign in to comment.