Skip to content

Commit

Permalink
Add rustls library and fix free identifier error message (#291)
Browse files Browse the repository at this point in the history
* add rustls and fix free identifier error message

* remove prints

* remove warnings

* more fixes

* fix warnings

* fix warning
  • Loading branch information
mattwparas authored Nov 23, 2024
1 parent 9a2bb2e commit af792c7
Show file tree
Hide file tree
Showing 13 changed files with 565 additions and 48 deletions.
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

0 comments on commit af792c7

Please sign in to comment.