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

Add rustls library and fix free identifier error message #291

Merged
merged 6 commits into from
Nov 23, 2024
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
258 changes: 224 additions & 34 deletions Cargo.lock

Large diffs are not rendered by default.

45 changes: 38 additions & 7 deletions crates/steel-core/src/compiler/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ impl DebruijnIndicesInterner {
instructions: &mut [Instruction],
symbol_map: &mut SymbolMap,
) -> Result<()> {
let mut flat_defines_non_closure: HashSet<InternedString> = HashSet::default();

for i in 2..instructions.len() {
match (&instructions[i], &instructions[i - 1], &instructions[i - 2]) {
(
Expand All @@ -93,11 +95,11 @@ impl DebruijnIndicesInterner {
..
},
) => {
// Exiting a definition, clear it
flat_defines_non_closure.clear();

let idx = symbol_map.add(s);
self.flat_defines.insert(s.to_owned());
// if !self.flat_defines.insert(s.to_owned()) {
// stop!(BadSyntax => format!("Cannot redefine define within the same scope: {}", s); *span);
// }

if let Some(x) = instructions.get_mut(i) {
x.payload_size = u24::from_usize(idx);
Expand All @@ -109,23 +111,48 @@ impl DebruijnIndicesInterner {
contents:
Some(Expr::Atom(SyntaxObject {
ty: TokenType::Identifier(s),
// span,
span,
..
})),
..
},
Instruction {
op_code: OpCode::EDEF,
..
},
..,
) => {
let idx = symbol_map.add(s);
self.flat_defines.insert(s.to_owned());
// if !self.flat_defines.insert(s.to_owned()) {
// stop!(BadSyntax => format!("Cannot redefine define within the same scope: {}", s); *span);
// }

if flat_defines_non_closure.contains(s) {
stop!(BadSyntax => format!("Cannot reference identifier before its definition: {}", s.resolve()); *span);
}

flat_defines_non_closure.clear();

// self.flat_defines_idx.insert(idx);
// flat_defines_non_closure.insert(s.to_owned());

if let Some(x) = instructions.get_mut(i) {
x.payload_size = u24::from_usize(idx);
}
}
(
Instruction {
op_code: OpCode::CALLGLOBAL,
contents:
Some(Expr::Atom(SyntaxObject {
ty: TokenType::Identifier(s),
..
})),
..
},
..,
) => {
// We're referencing things within the scope
flat_defines_non_closure.insert(*s);
}
_ => {}
}
}
Expand Down Expand Up @@ -181,6 +208,10 @@ impl DebruijnIndicesInterner {
} => {
// Keep track of where the defines actually are in the process
self.second_pass_defines.insert(s.to_owned());

// let idx = symbol_map.get(s).unwrap();

// self.second_pass_defines_idx.insert(idx);
}
Instruction {
op_code: OpCode::PUSH,
Expand Down
20 changes: 19 additions & 1 deletion crates/steel-core/src/primitives/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@ pub fn headers(value: &SteelVal) -> Result<SteelVal> {
))))
}

#[steel_derive::function(name = "http-response-headers")]
pub fn resp_headers(value: &SteelVal) -> Result<SteelVal> {
let resp = SteelResponse::as_ref(value)?;

Ok(SteelVal::HashMapV(SteelHashMap(Gc::new(
resp.headers
.iter()
.map(|x| {
(
SteelVal::StringV(x.name.clone().into()),
SteelVal::ByteVector(SteelByteVector::new(x.value.clone())),
)
})
.collect::<crate::values::HashMap<_, _>>(),
))))
}

// If not complete, try again?
fn parse_request(buf: &[u8]) -> Result<SteelVal> {
// Pull more bytes from the stream?
Expand Down Expand Up @@ -121,7 +138,7 @@ fn parse_request(buf: &[u8]) -> Result<SteelVal> {

fn parse_response(buf: &[u8]) -> Result<SteelVal> {
// Pull more bytes from the stream?
let mut headers = [httparse::EMPTY_HEADER; 16];
let mut headers = [httparse::EMPTY_HEADER; 64];
let mut req = httparse::Response::new(&mut headers);
let res = req.parse(&buf).unwrap();
if res.is_complete() {
Expand Down Expand Up @@ -171,6 +188,7 @@ pub fn http_module() -> BuiltInModule {
.register_native_fn_definition(PATH_DEFINITION)
.register_native_fn_definition(BODY_OFFSET_DEFINITION)
.register_native_fn_definition(HEADERS_DEFINITION)
.register_native_fn_definition(RESP_HEADERS_DEFINITION)
.register_native_fn_definition(PARSE_HTTP_RESPONSE_DEFINITION);

// module
Expand Down
5 changes: 4 additions & 1 deletion crates/steel-core/src/scheme/modules/parameters.scm
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@

(define write-char #%raw-write-char)

(define write #%raw-write)
(define write
(case-lambda
[(arg) (#%raw-write arg (current-output-port))]
[(arg port) (#%raw-write arg port)]))

;;;;;;;;;;;;;;;;;;;;; Port functions ;;;;;;;;;;;;;;;;;;;;;

Expand Down
84 changes: 82 additions & 2 deletions crates/steel-core/src/steel_vm/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
borrow::Cow,
io::BufReader,
marker::PhantomData,
sync::{Arc, Mutex},
};
Expand All @@ -14,7 +15,11 @@ use crate::{
as_underlying_type_mut, Custom, CustomType, FutureResult, IntoSteelVal,
MaybeSendSyncStatic, Result, SteelByteVector, SteelHashMap, SteelVal,
},
values::functions::{BoxedDynFunction, StaticOrRcStr},
values::{
functions::{BoxedDynFunction, StaticOrRcStr},
port::SteelPort,
SteelPortRepr,
},
SteelErr,
};

Expand All @@ -23,7 +28,7 @@ use abi_stable::{
std_types::{
RArc, RBoxError, RCowStr, RHashMap, RResult, RSlice, RSliceMut, RStr, RString, RVec, Tuple2,
},
RMut, StableAbi,
DynTrait, RMut, StableAbi,
};
use futures_util::FutureExt;

Expand Down Expand Up @@ -331,6 +336,16 @@ impl<'a> FromFFIArg<'a> for RSliceMut<'a, FFIValue> {
}
}

impl<'a> FromFFIArg<'a> for RVec<u8> {
fn from_ffi_arg(val: FFIArg<'a>) -> RResult<Self, RBoxError> {
if let FFIArg::ByteVector(b) = val {
RResult::ROk(b)
} else {
conversion_error!(bytevector, val)
}
}
}

impl<'a, T: Custom + Clone + 'static> FromFFIArg<'a> for T {
fn from_ffi_arg(val: FFIArg<'a>) -> RResult<Self, RBoxError> {
let lifted = unsafe { std::mem::transmute::<FFIArg<'a>, FFIArg<'static>>(val) };
Expand Down Expand Up @@ -929,6 +944,52 @@ macro_rules! declare_module {
};
}

#[repr(C)]
#[derive(StableAbi)]
#[sabi(impl_InterfaceType(Sync, Send, IoWrite))]
pub struct WriterInterface;

#[repr(C)]
#[derive(StableAbi)]
#[sabi(impl_InterfaceType(Sync, Send, IoRead))]
pub struct ReaderInterface;

#[repr(C)]
#[derive(StableAbi)]
pub struct DynWriter {
pub writer: DynTrait<'static, RBox<()>, WriterInterface>,
}

impl DynWriter {
fn into_port(self) -> SteelPortRepr {
SteelPortRepr::DynWriter(Arc::new(Mutex::new(self.writer)))
}
}

#[repr(C)]
#[derive(StableAbi)]
pub struct DynReader {
pub reader: DynTrait<'static, RBox<()>, ReaderInterface>,
}

impl DynReader {
fn into_port(self) -> SteelPortRepr {
SteelPortRepr::DynReader(BufReader::new(Box::new(self.reader)))
}
}

impl IntoFFIVal for DynWriter {
fn into_ffi_val(self) -> RResult<FFIValue, RBoxError> {
RResult::ROk(FFIValue::DynWriter(self))
}
}

impl IntoFFIVal for DynReader {
fn into_ffi_val(self) -> RResult<FFIValue, RBoxError> {
RResult::ROk(FFIValue::DynReader(self))
}
}

#[repr(C)]
#[derive(StableAbi)]
pub struct MutableString {
Expand All @@ -937,6 +998,8 @@ pub struct MutableString {

impl Custom for MutableString {}

#[repr(C)]
#[derive(StableAbi)]
struct FFIVector {
vec: RVec<FFIValue>,
}
Expand Down Expand Up @@ -1012,6 +1075,7 @@ pub enum FFIArg<'a> {
fut: FfiFuture<RResult<FFIArg<'a>, RBoxError>>,
},
HostFunction(HostRuntimeFunction),
ByteVector(RVec<u8>),
}

impl<'a> std::default::Default for FFIArg<'a> {
Expand Down Expand Up @@ -1101,6 +1165,8 @@ pub enum FFIValue {
fut: SyncFfiFuture,
},
ByteVector(RVec<u8>),
DynWriter(DynWriter),
DynReader(DynReader),
}

#[repr(C)]
Expand Down Expand Up @@ -1167,6 +1233,8 @@ impl std::fmt::Debug for FFIValue {
FFIValue::HashMap(h) => write!(f, "{:?}", h),
FFIValue::Future { .. } => write!(f, "#<future>"),
FFIValue::ByteVector(b) => write!(f, "{:?}", b),
FFIValue::DynWriter(_) => write!(f, "#<ffi-writer>"),
FFIValue::DynReader(_) => write!(f, "#<ffi-reader>"),
}
}
}
Expand Down Expand Up @@ -1294,6 +1362,14 @@ impl IntoSteelVal for FFIValue {
)))),

Self::ByteVector(b) => Ok(SteelVal::ByteVector(SteelByteVector::new(b.into()))),

Self::DynWriter(d) => Ok(SteelVal::PortV(SteelPort {
port: Gc::new_mut(d.into_port()),
})),

Self::DynReader(d) => Ok(SteelVal::PortV(SteelPort {
port: Gc::new_mut(d.into_port()),
})),
}
}
}
Expand Down Expand Up @@ -1501,6 +1577,10 @@ fn as_ffi_argument(value: &SteelVal) -> Result<FFIArg<'_>> {
SteelVal::NumV(n) => Ok(FFIArg::NumV(*n)),
SteelVal::CharV(c) => Ok(FFIArg::CharV { c: *c }),
SteelVal::Void => Ok(FFIArg::Void),

// TODO: Find a way to not have to copy the whole byte vector
SteelVal::ByteVector(b) => Ok(FFIArg::ByteVector(b.vec.read().iter().copied().collect())),

// We can really only look at values that were made from the FFI boundary.
SteelVal::Custom(c) => {
// let mut guard = if let Ok(guard) = RefCell::try_borrow_mut(c) {
Expand Down
3 changes: 2 additions & 1 deletion crates/steel-core/src/values/json_vals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use steel_derive::function;
/// ```
#[function(name = "string->jsexpr")]
pub fn string_to_jsexpr(value: &SteelString) -> Result<SteelVal> {
let unescaped = unescape(&value);
// let unescaped = unescape(&value);
let unescaped = value;
let res: std::result::Result<Value, _> = serde_json::from_str(unescaped.as_str());

match res {
Expand Down
1 change: 1 addition & 0 deletions crates/steel-core/src/values/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ impl SteelPortRepr {
SteelPortRepr::StdInput(br) => port_read_str_fn!(br, read_to_string),
SteelPortRepr::ChildStdOutput(br) => port_read_str_fn!(br, read_to_string),
SteelPortRepr::ChildStdError(br) => port_read_str_fn!(br, read_to_string),
SteelPortRepr::DynReader(br) => port_read_str_fn!(br, read_to_string),
_x => stop!(Generic => "read-all-str"),
}
}
Expand Down
16 changes: 16 additions & 0 deletions libs/steel-rustls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "steel-rustls"
edition = "2021"
version.workspace = true

[lib]
name = "steel_rustls"
crate-type = ["rlib", "cdylib"]

[dependencies]
steel-core = { path = "../../crates/steel-core", version = "0.6.0", features = ["dylibs", "sync"] }
abi_stable = "0.11.1"
rustls = "0.23.17"
webpki-roots = "0.26"
flate2 = "1.0.35"

20 changes: 20 additions & 0 deletions libs/steel-rustls/rustls.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(#%require-dylib "libsteel_rustls" (only-in
client-connection
gz-decode
tcp-connect
tcp-reader
tcp-writer
tls-reader
tls-stream
tls-writer
))
(provide
client-connection
gz-decode
tcp-connect
tcp-reader
tcp-writer
tls-reader
tls-stream
tls-writer
)
Loading
Loading