Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uupdate js value covnersion #397

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 10 additions & 16 deletions crates/gosub_webexecutor/src/js/array.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
use crate::js::{JSRuntime, JSValue};
use crate::js::JSRuntime;
use gosub_shared::types::Result;

pub trait JSArray: Iterator {
type RT: JSRuntime;

fn get(
&self,
index: <Self::RT as JSRuntime>::ArrayIndex,
) -> Result<<Self::RT as JSRuntime>::Value>;
fn get(&self, index: usize) -> Result<<Self::RT as JSRuntime>::Value>;

fn set(
&self,
index: <Self::RT as JSRuntime>::ArrayIndex,
value: &<Self::RT as JSRuntime>::Value,
) -> Result<()>;
fn set(&self, index: usize, value: &<Self::RT as JSRuntime>::Value) -> Result<()>;

fn push(&self, value: <Self::RT as JSRuntime>::Value) -> Result<()>;

fn pop(&self) -> Result<<Self::RT as JSRuntime>::Value>;

fn remove<T: Into<<Self::RT as JSRuntime>::ArrayIndex>>(&self, index: T) -> Result<()>;
fn remove(&self, index: usize) -> Result<()>;

fn len(&self) -> <Self::RT as JSRuntime>::ArrayIndex;
fn len(&self) -> usize;

fn is_empty(&self) -> bool;

fn new(
ctx: <Self::RT as JSRuntime>::Context,
cap: <Self::RT as JSRuntime>::ArrayIndex,
) -> Result<Self>
fn new(ctx: <Self::RT as JSRuntime>::Context, cap: usize) -> Result<Self>
where
Self: Sized;

Expand All @@ -38,4 +28,8 @@ pub trait JSArray: Iterator {
) -> Result<Self>
where
Self: Sized;

fn as_value(&self) -> <Self::RT as JSRuntime>::Value;

fn as_vec(&self) -> Vec<<Self::RT as JSRuntime>::Value>;
}
2 changes: 1 addition & 1 deletion crates/gosub_webexecutor/src/js/compile.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gosub_shared::types::Result;

use crate::js::{JSContext, JSRuntime, JSValue};
use crate::js::JSRuntime;

//compiled code will be stored with this trait for later execution (e.g HTML parsing not done yet)
pub trait JSCompiled {
Expand Down
2 changes: 1 addition & 1 deletion crates/gosub_webexecutor/src/js/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gosub_shared::types::Result;

use crate::js::{JSArray, JSCompiled, JSFunction, JSObject, JSRuntime, JSValue};
use crate::js::JSRuntime;

//main trait for JS context (can be implemented for different JS engines like V8, SpiderMonkey, JSC, etc.)
pub trait JSContext: Clone {
Expand Down
4 changes: 1 addition & 3 deletions crates/gosub_webexecutor/src/js/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use core::fmt::Display;

use gosub_shared::types::Result;

use crate::js::{JSContext, JSObject, JSRuntime, JSValue};

struct Function<T: JSFunction>(pub T);
use crate::js::JSRuntime;

//trait for JS functions (interop between JS and Rust)
pub trait JSFunction {
Expand Down
2 changes: 1 addition & 1 deletion crates/gosub_webexecutor/src/js/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::fmt::Display;

use gosub_shared::types::Result;

use crate::js::{JSContext, JSFunction, JSFunctionVariadic, JSRuntime, JSValue};
use crate::js::JSRuntime;

pub trait JSObject {
type RT: JSRuntime;
Expand Down
1 change: 0 additions & 1 deletion crates/gosub_webexecutor/src/js/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ pub trait JSRuntime {
type Function: JSFunction<RT = Self>;
type FunctionVariadic: JSFunctionVariadic<RT = Self>;
type Array: JSArray<RT = Self>;
type ArrayIndex;
type FunctionCallBack: JSFunctionCallBack<RT = Self>;
type FunctionCallBackVariadic: JSFunctionCallBackVariadic<RT = Self>;
type Args: Args<RT = Self>;
Expand Down
9 changes: 3 additions & 6 deletions crates/gosub_webexecutor/src/js/v8.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::any::Any;
use std::cell::RefCell;
use std::ops::{Deref, DerefMut};

use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;
Expand All @@ -13,7 +12,7 @@ use gosub_shared::types::Result;
pub use object::*;
pub use value::*;

use crate::js::{JSArray, JSContext, JSFunction, JSObject, JSRuntime, JSValue, ValueConversion};
use crate::js::JSRuntime;

mod array;
mod compile;
Expand Down Expand Up @@ -106,7 +105,6 @@ impl<'a> JSRuntime for V8Engine<'a> {
type Function = V8Function<'a>;
type FunctionVariadic = V8FunctionVariadic<'a>;
type Array = V8Array<'a>;
type ArrayIndex = u32;
type FunctionCallBack = V8FunctionCallBack<'a>;
type FunctionCallBackVariadic = V8FunctionCallBackVariadic<'a>;
type Args = V8Args<'a>;
Expand All @@ -125,14 +123,13 @@ impl<'a> JSRuntime for V8Engine<'a> {

#[cfg(test)]
mod tests {
use anyhow;

use crate::js::v8::V8_INITIALIZED;
use crate::js::{JSContext, JSRuntime, JSValue};

#[test]
fn v8_engine_initialization() {
let mut engine = crate::js::v8::V8Engine::new();
let _engine = crate::js::v8::V8Engine::new();

assert!(V8_INITIALIZED.is_completed());
}
Expand Down
91 changes: 70 additions & 21 deletions crates/gosub_webexecutor/src/js/v8/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ impl<'a> Iterator for V8Array<'a> {
impl<'a> JSArray for V8Array<'a> {
type RT = V8Engine<'a>;

fn get(&self, index: u32) -> Result<<Self::RT as JSRuntime>::Value> {
let Some(value) = self.value.get_index(self.ctx.borrow_mut().scope(), index) else {
fn get(&self, index: usize) -> Result<<Self::RT as JSRuntime>::Value> {
let Some(value) = self
.value
.get_index(self.ctx.borrow_mut().scope(), index as u32)
else {
return Err(Error::JS(JSError::Generic(
"failed to get a value from an array".to_owned(),
))
Expand All @@ -49,10 +52,10 @@ impl<'a> JSArray for V8Array<'a> {
Ok(V8Value::from_value(self.ctx.clone(), value))
}

fn set(&self, index: u32, value: &V8Value) -> Result<()> {
fn set(&self, index: usize, value: &V8Value) -> Result<()> {
match self
.value
.set_index(self.ctx.borrow_mut().scope(), index, value.value)
.set_index(self.ctx.borrow_mut().scope(), index as u32, value.value)
{
Some(_) => Ok(()),
None => Err(Error::JS(JSError::Conversion(
Expand Down Expand Up @@ -100,10 +103,10 @@ impl<'a> JSArray for V8Array<'a> {
Ok(V8Value::from_value(self.ctx.clone(), value))
}

fn remove<T: Into<u32>>(&self, index: T) -> Result<()> {
fn remove(&self, index: usize) -> Result<()> {
if self
.value
.delete_index(self.ctx.borrow_mut().scope(), index.into())
.delete_index(self.ctx.borrow_mut().scope(), index as u32)
.is_none()
{
return Err(Error::JS(JSError::Generic(
Expand All @@ -115,15 +118,15 @@ impl<'a> JSArray for V8Array<'a> {
Ok(())
}

fn len(&self) -> u32 {
self.value.length()
fn len(&self) -> usize {
self.value.length() as usize
}

fn is_empty(&self) -> bool {
self.value.length() == 0
}

fn new(ctx: V8Context<'a>, cap: u32) -> Result<Self> {
fn new(ctx: V8Context<'a>, cap: usize) -> Result<Self> {
let value = Array::new(ctx.borrow_mut().scope(), cap as i32);

Ok(Self {
Expand All @@ -143,19 +146,32 @@ impl<'a> JSArray for V8Array<'a> {
next: 0,
})
}

fn as_value(&self) -> <Self::RT as JSRuntime>::Value {
V8Value::from_value(self.ctx.clone(), Local::from(self.value))
}

fn as_vec(&self) -> Vec<<Self::RT as JSRuntime>::Value> {
let mut vec = Vec::with_capacity(self.len());
for i in 0..self.len() {
vec.push(self.get(i).unwrap());
}
vec
}
}

#[cfg(test)]
mod tests {
use crate::js::v8::{V8Array, V8Engine};
use crate::js::v8::{V8Array, V8Engine, V8Value};
use crate::js::{
ArrayConversion, JSArray, JSContext, JSObject, JSRuntime, JSValue, ValueConversion,
ArrayConversion, IntoJSValue, IntoRustValue, JSArray, JSContext, JSObject, JSRuntime,
JSValue,
};

#[test]
fn set() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();
array
Expand All @@ -171,7 +187,7 @@ mod tests {
#[test]
fn get() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();

Expand All @@ -189,7 +205,7 @@ mod tests {
#[test]
fn push() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();

Expand All @@ -206,7 +222,7 @@ mod tests {
#[test]
fn out_of_bounds() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();

Expand All @@ -223,7 +239,7 @@ mod tests {
#[test]
fn pop() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();

Expand All @@ -235,14 +251,14 @@ mod tests {
.unwrap();

assert_eq!(array.pop().unwrap().as_string().unwrap(), "Hello World!");
assert_eq!(array.get(0u32).unwrap().as_number().unwrap(), 1234.0);
assert!(array.get(1u32).unwrap().is_undefined());
assert_eq!(array.get(0).unwrap().as_number().unwrap(), 1234.0);
assert!(array.get(1).unwrap().is_undefined());
}

#[test]
fn dynamic_resize() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array = V8Array::new(context.clone(), 2).unwrap();

Expand All @@ -265,7 +281,7 @@ mod tests {
#[test]
fn rust_to_js() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

let array: V8Array = [42, 1337, 1234].to_js_array(context.clone()).unwrap();

Expand All @@ -275,6 +291,21 @@ mod tests {
assert_eq!(array.get(2).unwrap().as_number().unwrap(), 1234.0);
}

#[test]
fn rust_to_js_value() {
let mut engine = V8Engine::new();
let context = engine.new_context().unwrap();

let array: V8Value = [42, 1337, 1234].to_js_value(context.clone()).unwrap();

assert!(array.is_array());
let array = array.as_array().unwrap();
assert_eq!(array.len(), 3);
assert_eq!(array.get(0).unwrap().as_number().unwrap(), 42.0);
assert_eq!(array.get(1).unwrap().as_number().unwrap(), 1337.0);
assert_eq!(array.get(2).unwrap().as_number().unwrap(), 1234.0);
}

#[test]
fn rust_to_js_global() {
let mut engine = V8Engine::new();
Expand Down Expand Up @@ -384,7 +415,7 @@ mod tests {
#[test]
fn rust_vec_to_js() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();
let context = engine.new_context().unwrap();

#[allow(clippy::useless_vec)]
let vec = vec![42, 1337, 1234];
Expand All @@ -396,4 +427,22 @@ mod tests {
assert_eq!(array.get(1).unwrap().as_number().unwrap(), 1337.0);
assert_eq!(array.get(2).unwrap().as_number().unwrap(), 1234.0);
}

#[test]
fn js_vec_to_rust() {
let mut engine = V8Engine::new();
let mut context = engine.new_context().unwrap();

let array = context
.run(
r#"
[42, 1337, 1234]
"#,
)
.unwrap();

let vec: Vec<u32> = array.as_array().unwrap().to_rust_value().unwrap();

assert_eq!(vec, vec![42, 1337, 1234]);
}
}
10 changes: 4 additions & 6 deletions crates/gosub_webexecutor/src/js/v8/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ impl Copied {
}

pub(crate) enum HandleScopeType<'a> {
WithContext(HandleScope<'a>),
WithContextRef(&'a mut HandleScope<'a>),
WithoutContext(HandleScope<'a, ()>),
CallbackScope(CallbackScope<'a>),
Expand All @@ -57,7 +56,6 @@ impl<'a> HandleScopeType<'a> {

pub(crate) fn get(&mut self) -> &mut HandleScope<'a, ()> {
match self {
Self::WithContext(scope) => scope,
Self::WithoutContext(scope) => scope,
Self::CallbackScope(scope) => scope,
Self::WithContextRef(scope) => scope,
Expand Down Expand Up @@ -121,9 +119,9 @@ impl<'a> V8Ctx<'a> {
unsafe { self.context_scope.as_mut() }
}

pub(crate) fn handle_scope(&mut self) -> &'a mut HandleScope<'a, ()> {
unsafe { self.handle_scope.as_mut() }.get()
}
// pub(crate) fn handle_scope(&mut self) -> &'a mut HandleScope<'a, ()> {
// unsafe { self.handle_scope.as_mut() }.get()
// }

pub(crate) fn context(&mut self) -> &'a mut Local<'a, v8::Context> {
unsafe { self.ctx.as_mut() }
Expand Down Expand Up @@ -217,7 +215,7 @@ pub(crate) fn ctx_from_scope_isolate<'a>(
}

pub(crate) fn ctx_from_function_callback_info(
mut scope: CallbackScope,
scope: CallbackScope,
isolate: NonNull<OwnedIsolate>,
) -> std::result::Result<V8Context, (HandleScopeType, Error)> {
let ctx = scope.get_current_context();
Expand Down
Loading
Loading