Skip to content

Commit

Permalink
James/scale 34 time based global functions kill function execution (#127
Browse files Browse the repository at this point in the history
)

* First implementation of async scale run working e2e

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* WIP getting setTimeout to work

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* js timers/timeout working e2e.

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* clearTimeout and clearInterval working

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Moved some things into quickjs for promise inspection

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Split out separate int test for ts setTimeout setInterval clearTimeout clearInterval

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Refactor time.rs to use trigger_time.elapsed()

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Add: js_builder-x86_64-unknown-linux-gnu

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-aarch64-unknown-linux-gnu

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-x86_64-pc-windows-msvc

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-aarch64-apple-darwin

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-x86_64-apple-darwin

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Tidied up error handling and comments

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Fixed typo

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>

* Add: js_builder-x86_64-unknown-linux-gnu

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-aarch64-unknown-linux-gnu

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-x86_64-pc-windows-msvc

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-x86_64-apple-darwin

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Add: js_builder-aarch64-apple-darwin

Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

---------

Signed-off-by: Jimmy Moore <jamesmoore@loopholelabs.io>
Signed-off-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
jimmyaxod and github-actions[bot] authored Jan 17, 2024
1 parent fc872af commit f0e29d3
Show file tree
Hide file tree
Showing 98 changed files with 106,952 additions and 10 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_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 @@ -99,6 +103,8 @@ fn initialize_runtime() {
JS_PROP_C_W_E as i32,
);

time::install(context);

helpers::set_callback(
context,
global,
Expand Down Expand Up @@ -216,6 +222,7 @@ fn initialize_runtime() {
ENTRY_RESIZE.set(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 @@ -320,19 +327,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 f0e29d3

Please sign in to comment.