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

Xavierm02/streams/underlying source #240

Closed
wants to merge 6 commits into from
Closed
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
17 changes: 17 additions & 0 deletions crates/jstz_api/src/idl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,20 @@ impl ArrayBufferLike for JsBufferSource {
}
}
}

// https://webidl.spec.whatwg.org/#idl-types

pub type Any = JsValue;
pub type Bytes = i8;
pub type Octet = u8;
pub type Short = i16;
pub type UnsignedShort = u16;
pub type Long = i32;
pub type UnsignedLong = u32;
pub type LongLong = i64;
pub type UnsignedLongLong = u64;
pub type UnrestrictedFloat = f32;
pub type UnrestrictedDouble = f64;

pub type PositiveInteger = UnsignedLongLong;
pub type Number = f64;
2 changes: 2 additions & 0 deletions crates/jstz_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mod kv;
pub mod encoding;
pub mod http;
pub mod idl;
pub mod stream;
pub mod todo;
pub mod url;
pub mod urlpattern;
pub use console::{ConsoleApi, LogRecord, LOG_PREFIX};
Expand Down
14 changes: 14 additions & 0 deletions crates/jstz_api/src/stream/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use boa_engine::Context;

use self::readable::ReadableStreamApi;

pub mod readable;
mod tmp;

pub struct StreamApi;

impl jstz_core::Api for StreamApi {
fn init(self, context: &mut Context<'_>) {
ReadableStreamApi.init(context);
}
}
58 changes: 58 additions & 0 deletions crates/jstz_api/src/stream/readable/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use boa_engine::{value::TryFromJs, Context, JsArgs, JsResult};
use boa_gc::{custom_trace, Finalize, Trace};
use jstz_core::native::{
register_global_class, ClassBuilder, JsNativeObject, NativeClass,
};

use crate::stream::readable::underlying_source::{
UnderlyingSource, UnderlyingSourceTrait,
};

pub mod underlying_source;

pub struct ReadableStream {
// TODO
}

impl Finalize for ReadableStream {
fn finalize(&self) {
todo!()
}
}

unsafe impl Trace for ReadableStream {
custom_trace!(this, todo!());
}

pub struct ReadableStreamClass;

impl NativeClass for ReadableStreamClass {
type Instance = ReadableStream;

const NAME: &'static str = "ReadableStream";

fn constructor(
_this: &JsNativeObject<Self::Instance>,
args: &[boa_engine::JsValue],
context: &mut Context<'_>,
) -> JsResult<Self::Instance> {
let underlying_source =
Option::<UnderlyingSource>::try_from_js(args.get_or_undefined(0), context)?;
todo!()
}

fn init(class: &mut ClassBuilder<'_, '_>) -> JsResult<()> {
// TODO
Ok(())
}
}

pub struct ReadableStreamApi;

impl jstz_core::Api for ReadableStreamApi {
fn init(self, context: &mut Context<'_>) {
register_global_class::<ReadableStreamClass>(context)
.expect("The `ReadableStream` class shouldn't exist yet")
// TODO
}
}
411 changes: 411 additions & 0 deletions crates/jstz_api/src/stream/readable/underlying_source.rs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions crates/jstz_api/src/stream/tmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Temporary definitions to allow compiling before defining all types

use crate::todo::Todo;

pub type ReadableStreamDefaultController = Todo;
pub type ReadableByteStreamController = Todo;
40 changes: 40 additions & 0 deletions crates/jstz_api/src/todo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use boa_engine::value::TryFromJs;
use boa_gc::{custom_trace, Finalize, Trace};
use jstz_core::value::IntoJs;

/// A placeholder for types that have yet to be defined
#[derive(Debug)]
pub enum Todo {
Todo,
}

impl Finalize for Todo {
fn finalize(&self) {
todo!()
}
}

#[allow(unused_variables)]
unsafe impl Trace for Todo {
custom_trace!(this, todo!());
}

#[allow(unused_variables)]
impl IntoJs for Todo {
fn into_js(
self,
context: &mut boa_engine::prelude::Context<'_>,
) -> boa_engine::prelude::JsValue {
todo!()
}
}

#[allow(unused_variables)]
impl TryFromJs for Todo {
fn try_from_js(
value: &boa_engine::prelude::JsValue,
context: &mut boa_engine::prelude::Context<'_>,
) -> boa_engine::prelude::JsResult<Self> {
todo!()
}
}
3 changes: 2 additions & 1 deletion crates/jstz_cli/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::Result;
use boa_engine::{js_string, JsResult, JsValue, Source};
use jstz_api::{
encoding::EncodingApi, http::HttpApi, url::UrlApi, urlpattern::UrlPatternApi,
ConsoleApi, KvApi,
ConsoleApi, KvApi, stream::StreamApi
};
use jstz_core::host::HostRuntime;
use jstz_core::{
Expand Down Expand Up @@ -48,6 +48,7 @@ pub fn exec(self_address: Option<String>, cfg: &Config) -> Result<()> {
rt.context(),
);
realm_clone.register_api(EncodingApi, rt.context());
realm_clone.register_api(StreamApi, rt.context());
realm_clone.register_api(UrlApi, rt.context());
realm_clone.register_api(UrlPatternApi, rt.context());
realm_clone.register_api(HttpApi, rt.context());
Expand Down
136 changes: 136 additions & 0 deletions crates/jstz_core/src/js_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
use std::{marker::PhantomData, ops::Deref};

use boa_engine::{
object::builtins::JsFunction, value::TryFromJs, Context, JsResult, JsValue,
};
use boa_gc::{custom_trace, Finalize, Trace};

use crate::value::IntoJs;

pub trait IntoJsArgs<const N: usize> {
fn into_js_args(self, context: &mut Context<'_>) -> [JsValue; N];
}

impl IntoJsArgs<0> for () {
fn into_js_args(self, _context: &mut Context<'_>) -> [JsValue; 0] {
[]
}
}

impl<T0: IntoJs> IntoJsArgs<1> for (T0,) {
fn into_js_args(self, context: &mut Context<'_>) -> [JsValue; 1] {
[self.0.into_js(context)]
}
}

impl<T0: IntoJs, T1: IntoJs> IntoJsArgs<2> for (T0, T1) {
fn into_js_args(self, context: &mut Context<'_>) -> [JsValue; 2] {
[self.0.into_js(context), self.1.into_js(context)]
}
}

impl<T0: IntoJs, T1: IntoJs, T2: IntoJs> IntoJsArgs<3> for (T0, T1, T2) {
fn into_js_args(self, context: &mut Context<'_>) -> [JsValue; 3] {
[
self.0.into_js(context),
self.1.into_js(context),
self.2.into_js(context),
]
}
}

/// A `JsFn<T, N, I, O>` is a `JsFunction` tagged with some Rust types used to handle the `TryFromJs` and `IntoJs` conversions automatically:
/// - `T` is the type of the `this` parameter;
/// - `N` is the arity;
/// - `I` is a tuple `(I1, ..., IN)` that contains the types of the parameters;
/// - `O` is the type of the output.
#[derive(Debug)]
pub struct JsFn<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> {
function: JsFunction,
_this_type: PhantomData<T>,
_inputs_type: PhantomData<I>,
_output_type: PhantomData<O>,
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> Finalize
for JsFn<T, N, I, O>
{
fn finalize(&self) {}
}

unsafe impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> Trace
for JsFn<T, N, I, O>
{
custom_trace!(this, {
mark(&this.function);
});
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> Deref
for JsFn<T, N, I, O>
{
type Target = JsFunction;

fn deref(&self) -> &Self::Target {
&self.function
}
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> Into<JsFunction>
for JsFn<T, N, I, O>
{
fn into(self) -> JsFunction {
self.function
}
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> From<JsFunction>
for JsFn<T, N, I, O>
{
fn from(value: JsFunction) -> Self {
JsFn {
function: value,
_this_type: PhantomData,
_inputs_type: PhantomData,
_output_type: PhantomData,
}
}
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> Into<JsValue>
for JsFn<T, N, I, O>
{
fn into(self) -> JsValue {
self.function.into()
}
}

// impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> TryFrom<JsValue> for JsFn<T, N, I, O>
// This is implementable, but the right way to implement it would be to lift the implementation of `TryFromJs` for `JsFunction` (that does not use the context) to an implementation of `TryFrom<JsFunction>` in boa
// (If it is eventually implemented, then the implementation of TryFromJs below should use it)

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> IntoJs
for JsFn<T, N, I, O>
{
fn into_js(self, _context: &mut Context<'_>) -> JsValue {
self.function.into()
}
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> TryFromJs
for JsFn<T, N, I, O>
{
fn try_from_js(value: &JsValue, context: &mut Context<'_>) -> JsResult<Self> {
JsFunction::try_from_js(value, context).map(JsFn::from)
}
}

impl<T: IntoJs, const N: usize, I: IntoJsArgs<N>, O: TryFromJs> JsFn<T, N, I, O> {
pub fn call(&self, this: T, inputs: I, context: &mut Context<'_>) -> JsResult<O> {
let js_this = this.into_js(context);
let js_args = inputs.into_js_args(context);
self.deref()
.call(&js_this, &js_args, context)
.and_then(|output| O::try_from_js(&output, context))
}
}
1 change: 1 addition & 0 deletions crates/jstz_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use error::{Error, Result};
pub mod future;
pub mod host;
pub mod iterators;
pub mod js_fn;
pub mod kv;
pub mod native;
pub mod realm;
Expand Down
2 changes: 1 addition & 1 deletion crates/jstz_core/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub use boa_engine::{object::NativeObject, NativeFunction};
use crate::value::IntoJs;

/// This struct permits Rust types to be passed around as JavaScript objects.
#[derive(Trace, Finalize)]
#[derive(Trace, Finalize, Debug)]
pub struct JsNativeObject<T: NativeObject> {
inner: JsValue,
_phantom: PhantomData<T>,
Expand Down
1 change: 1 addition & 0 deletions crates/jstz_core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub trait IntoJs {
fn into_js(self, context: &mut Context<'_>) -> JsValue;
}

#[macro_export]
macro_rules! impl_into_js_from_into {
($($T: ty), *) => {
$(
Expand Down
Loading