Skip to content

Commit 179b9a1

Browse files
committed
Fix stuff, change format to JSON
1 parent edf4464 commit 179b9a1

File tree

6 files changed

+102
-70
lines changed

6 files changed

+102
-70
lines changed

cobalt-ast/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ serde_derive_state = "0.4.10"
3131
const-identify = "0.1.1"
3232
erased-serde = "0.4.1"
3333
deranged = { version = "0.3.10", features = ["serde"] }
34-
serde-value = "0.7.0"
35-
serde_cbor = "0.11.2"
34+
serde_json = "1.0.111"
35+
hex = { version = "0.4.3", features = ["serde"] }
36+
serde_bytes = "0.11.14"

cobalt-ast/src/context.rs

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use inkwell::{builder::Builder, context::Context, module::Module};
88
use owned_chars::OwnedCharsExt;
99
use serde::de::DeserializeSeed;
1010
use std::cell::{Cell, RefCell};
11+
use std::fmt::{self, Debug, Formatter};
1112
use std::io::{Read, Write};
1213
use std::mem::MaybeUninit;
1314
use std::pin::Pin;
@@ -286,11 +287,11 @@ impl<'src, 'ctx> CompCtx<'src, 'ctx> {
286287
}
287288
Some(v)
288289
}
289-
pub fn save<W: Write>(&self, out: &mut W) -> serde_cbor::Result<()> {
290-
serde_cbor::to_writer(out, self)
290+
pub fn save<W: Write>(&self, buf: &mut W) -> serde_json::Result<()> {
291+
serde_json::to_writer(buf, self)
291292
}
292-
pub fn load<R: Read>(&self, buf: &mut R) -> serde_cbor::Result<Vec<String>> {
293-
self.deserialize(&mut serde_cbor::Deserializer::from_reader(buf))
293+
pub fn load<R: Read>(&self, buf: &mut R) -> serde_json::Result<Vec<String>> {
294+
self.deserialize(&mut serde_json::Deserializer::from_reader(buf))
294295
}
295296
}
296297
impl Drop for CompCtx<'_, '_> {
@@ -319,7 +320,9 @@ impl<'de, T, F: FnOnce(&mut dyn erased_serde::Deserializer) -> Result<T, erased_
319320
.map_err(de::Error::custom)
320321
}
321322
}
322-
323+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
324+
#[serde(transparent)]
325+
struct HexArray(#[serde(with = "hex::serde")] [u8; 8]);
323326
struct CtxTypeSerde<'a, 's, 'c>(&'a CompCtx<'s, 'c>);
324327
impl Serialize for CtxTypeSerde<'_, '_, '_> {
325328
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -330,7 +333,7 @@ impl Serialize for CtxTypeSerde<'_, '_, '_> {
330333
let tsr = TYPE_SERIAL_REGISTRY.pin();
331334
let mut map = serializer.serialize_map(Some(tsr.len()))?;
332335
for (id, info) in &tsr {
333-
map.serialize_entry(id, &(info.erased_header)())?;
336+
map.serialize_entry(&HexArray(id.to_le_bytes()), &(info.erased_header)())?;
334337
}
335338
map.end()
336339
}
@@ -345,8 +348,8 @@ impl<'de> de::Visitor<'de> for CtxTypeSerde<'_, '_, '_> {
345348
A: de::MapAccess<'de>,
346349
{
347350
let tsr = TYPE_SERIAL_REGISTRY.pin();
348-
while let Some(id) = map.next_key::<u64>()? {
349-
let Some(loader) = tsr.get(&id) else {
351+
while let Some(id) = map.next_key::<HexArray>()? {
352+
let Some(loader) = tsr.get(&u64::from_le_bytes(id.0)) else {
350353
return Err(de::Error::custom("unknown type ID {:0>16x}"));
351354
};
352355
map.next_value_seed(FnDeserializer(loader.load_header))?;
@@ -371,10 +374,12 @@ impl Serialize for CompCtx<'_, '_> {
371374
use ser::*;
372375
#[allow(clippy::unnecessary_cast)]
373376
SERIALIZATION_CONTEXT.with(|c| {
374-
if let Some(ptr) = c.replace(Some(
377+
if let Some(ptr) = c.replace(Some(ContextPointer::new(
375378
self as *const CompCtx<'_, '_> as *const CompCtx<'static, 'static>, // this intermediate cast is necessary
376-
)) {
377-
panic!("serialization context is already in use with an address of {ptr:p}");
379+
))) {
380+
if *ptr != (self as *const CompCtx<'_, '_> as *const CompCtx<'static, 'static>) {
381+
panic!("serialization context is already in use with an address of {ptr:#?}");
382+
}
378383
}
379384
});
380385
let mut map = serializer.serialize_struct("Context", 3)?;
@@ -406,10 +411,12 @@ impl<'de> DeserializeSeed<'de> for &CompCtx<'_, '_> {
406411
use de::*;
407412
#[allow(clippy::unnecessary_cast)]
408413
SERIALIZATION_CONTEXT.with(|c| {
409-
if let Some(ptr) = c.replace(Some(
414+
if let Some(ptr) = c.replace(Some(ContextPointer::new(
410415
self as *const CompCtx<'_, '_> as *const CompCtx<'static, 'static>, // this intermediate cast is necessary
411-
)) {
412-
panic!("serialization context is already in use with an address of {ptr:p}");
416+
))) {
417+
if *ptr != (self as *const CompCtx<'_, '_> as *const CompCtx<'static, 'static>) {
418+
panic!("serialization context is already in use with an address of {ptr:#?}");
419+
}
413420
}
414421
});
415422
let proxy = ContextDeProxy::deserialize(deserializer)?;
@@ -429,7 +436,57 @@ impl<'de> DeserializeSeed<'de> for &CompCtx<'_, '_> {
429436
Ok(self.with_vars(|v| varmap::merge(&mut v.symbols, vars.symbols)))
430437
}
431438
}
439+
440+
/// Wrapper around a context pointer, maybe with a backtace
441+
pub struct ContextPointer {
442+
ptr: *const CompCtx<'static, 'static>,
443+
#[cfg(debug_assertions)]
444+
trace: std::backtrace::Backtrace,
445+
}
446+
impl ContextPointer {
447+
pub fn new(ptr: *const CompCtx<'static, 'static>) -> Self {
448+
Self {
449+
trace: std::backtrace::Backtrace::capture(),
450+
ptr,
451+
}
452+
}
453+
}
454+
impl std::ops::Deref for ContextPointer {
455+
type Target = *const CompCtx<'static, 'static>;
456+
fn deref(&self) -> &Self::Target {
457+
&self.ptr
458+
}
459+
}
460+
impl Debug for ContextPointer {
461+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
462+
write!(f, "{:p}", self.ptr)?;
463+
#[cfg(debug_assertions)]
464+
{
465+
if f.alternate() {
466+
if self.trace.status() == std::backtrace::BacktraceStatus::Captured {
467+
write!(f, "at: \n{}", self.trace)?;
468+
} else {
469+
f.write_str("without backtrace")?;
470+
}
471+
}
472+
}
473+
Ok(())
474+
}
475+
}
476+
/// Get the context pointer from a cell
477+
/// Super unsafe lmao
478+
///
479+
/// # Safety
480+
/// `SERIALIZATION_CONTEXT`` must be valid
481+
pub unsafe fn get_ctx_ptr<'a, 's, 'c>(cell: &Cell<Option<ContextPointer>>) -> &'a CompCtx<'s, 'c> {
482+
let opt = cell.replace(None);
483+
let cp = opt.expect("expected pointer in serialization context");
484+
let ptr = cp.ptr;
485+
cell.set(Some(cp));
486+
#[allow(clippy::unnecessary_cast)]
487+
&*(ptr as *const CompCtx<'s, 'c>)
488+
}
432489
thread_local! {
433-
/// CompCtx, should only have a value during deserialization
434-
pub static SERIALIZATION_CONTEXT: Cell<Option<*const CompCtx<'static, 'static>>> = const {Cell::new(None)};
490+
/// CompCtx, should only have a value during de/serialization
491+
pub static SERIALIZATION_CONTEXT: Cell<Option<ContextPointer>> = const {Cell::new(None)};
435492
}

cobalt-ast/src/types.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ impl Serialize for TypeRef {
703703
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
704704
use ser::*;
705705
let mut map = serializer.serialize_struct("Type", 3)?;
706-
map.serialize_field("kind", &self.kind())?;
706+
map.serialize_field("kind", &hex::encode(self.kind().to_le_bytes()))?;
707707
map.serialize_field("type", &self.erased_proxy())?;
708708
map.end()
709709
}
@@ -714,15 +714,16 @@ impl<'de> Deserialize<'de> for TypeRef {
714714
#[derive(Deserialize)]
715715
#[serde(bound = "'a: 'de")]
716716
struct Proxy<'a> {
717-
kind: u64,
717+
#[serde(with = "hex::serde")]
718+
kind: [u8; 8],
718719
#[serde(borrow, rename = "type")]
719720
ty: serde::__private::de::Content<'a>,
720721
}
721722
let p = Proxy::deserialize(deserializer)?;
722723
(TYPE_SERIAL_REGISTRY
723724
.pin()
724-
.get(&p.kind)
725-
.ok_or_else(|| D::Error::custom(format!("unknown type id {}", p.kind)))?
725+
.get(&u64::from_le_bytes(p.kind))
726+
.ok_or_else(|| D::Error::custom(format!("unknown type id {}", hex::encode(p.kind))))?
726727
.load)(&mut <dyn erased_serde::Deserializer>::erase(
727728
serde::__private::de::ContentDeserializer::<'de, D::Error>::new(p.ty),
728729
))

cobalt-ast/src/types/custom.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,7 @@ impl Serialize for CustomHeader {
196196
S: Serializer,
197197
{
198198
use ser::*;
199-
let ctx = SERIALIZATION_CONTEXT.with(|c| unsafe {
200-
&*c.get()
201-
.expect("type deserialization must be called with a context")
202-
});
199+
let ctx = SERIALIZATION_CONTEXT.with(|c| unsafe { get_ctx_ptr(c) });
203200
let cd = CUSTOM_DATA.pin();
204201
let mut map = serializer.serialize_map(Some(cd.len()))?;
205202
cd.iter()
@@ -214,10 +211,7 @@ impl<'de> Deserialize<'de> for CustomHeader {
214211
D: Deserializer<'de>,
215212
{
216213
use de::*;
217-
let ctx = SERIALIZATION_CONTEXT.with(|c| unsafe {
218-
&*c.get()
219-
.expect("type deserialization must be called with a context")
220-
});
214+
let ctx = SERIALIZATION_CONTEXT.with(|c| unsafe { get_ctx_ptr(c) });
221215
struct CHVisitor<'de, 'b, 'a, 's, 'c>(
222216
&'a CompCtx<'s, 'c>,
223217
flurry::Guard<'b>,

cobalt-ast/src/value.rs

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,8 @@ impl<'src, 'ctx> Value<'src, 'ctx> {
399399
#[serde(serialize_state = "()")]
400400
#[serde(de_parameters = "'a", deserialize_state = "&'a CompCtx<'src, 'ctx>")]
401401
struct ValueShim<'b, 'src, 'ctx> {
402-
pub loc: SourceSpan,
403402
#[serde(borrow)]
404-
pub comp_val: Option<&'b bstr::BStr>,
403+
pub comp_val: Option<Cow<'b, str>>,
405404
#[serde(deserialize_state)]
406405
pub inter_val: Option<Cow<'b, InterData<'src, 'ctx>>>,
407406
pub data_type: TypeRef,
@@ -410,20 +409,20 @@ struct ValueShim<'b, 'src, 'ctx> {
410409
impl<'src, 'ctx> Serialize for Value<'src, 'ctx> {
411410
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
412411
let Value {
413-
loc,
414412
comp_val,
415413
ref inter_val,
416414
data_type,
417415
frozen,
418416
..
419417
} = *self;
420418
ValueShim {
421-
loc,
422419
data_type,
423420
frozen,
424421
inter_val: inter_val.as_ref().map(Cow::Borrowed),
425422
comp_val: comp_val.map(|v| unsafe {
426-
new_lifetime(v.into_pointer_value().get_name().to_bytes().into())
423+
std::mem::transmute::<Cow<str>, Cow<str>>(String::from_utf8_lossy(
424+
v.into_pointer_value().get_name().to_bytes(),
425+
))
427426
}),
428427
}
429428
.serialize_state(serializer, &())
@@ -435,27 +434,25 @@ impl<'de, 'a, 'src, 'ctx> DeserializeState<'de, &'a CompCtx<'src, 'ctx>> for Val
435434
deserializer: D,
436435
) -> Result<Self, D::Error> {
437436
let ctx = *seed;
438-
ValueShim::deserialize_state(seed, deserializer).and_then(
437+
ValueShim::deserialize_state(seed, deserializer).map(
439438
|ValueShim {
440-
loc,
441439
comp_val,
442440
inter_val,
443441
data_type,
444442
frozen,
445443
}| {
446-
use de::Error;
447444
use inkwell::module::Linkage::DLLImport;
448445
let mut var = Value {
449-
loc,
450446
data_type,
451447
frozen,
452448
name: None,
453449
comp_val: None,
450+
loc: unreachable_span(),
454451
address: Default::default(),
455452
inter_val: inter_val.map(|iv| iv.into_owned()),
456453
};
457454
let Some(comp_val) = comp_val else {
458-
return Ok(var);
455+
return var;
459456
};
460457
if let Some(ty) = var
461458
.data_type
@@ -482,16 +479,7 @@ impl<'de, 'a, 'src, 'ctx> DeserializeState<'de, &'a CompCtx<'src, 'ctx>> for Val
482479
if good {
483480
if let Some(llt) = ty.ret().llvm_type(ctx) {
484481
let ft = llt.fn_type(&ps, false);
485-
let fv = ctx.module.add_function(
486-
std::str::from_utf8(comp_val).map_err(|_| {
487-
D::Error::invalid_value(
488-
de::Unexpected::Bytes(comp_val),
489-
&"a string",
490-
)
491-
})?,
492-
ft,
493-
None,
494-
);
482+
let fv = ctx.module.add_function(&comp_val, ft, None);
495483
if let Some(InterData::Function(FnData { cconv, .. })) = var.inter_val {
496484
fv.set_call_conventions(cconv)
497485
}
@@ -500,41 +488,26 @@ impl<'de, 'a, 'src, 'ctx> DeserializeState<'de, &'a CompCtx<'src, 'ctx>> for Val
500488
var.comp_val = Some(gv.as_pointer_value().into());
501489
} else if ty.ret().size() == SizeType::Static(0) {
502490
let ft = ctx.context.void_type().fn_type(&ps, false);
503-
let fv = ctx.module.add_function(
504-
std::str::from_utf8(comp_val).map_err(|_| {
505-
D::Error::invalid_value(
506-
de::Unexpected::Bytes(comp_val),
507-
&"a string",
508-
)
509-
})?,
510-
ft,
511-
None,
512-
);
491+
let fv = ctx.module.add_function(&comp_val, ft, None);
513492
if let Some(InterData::Function(FnData { cconv, .. })) = var.inter_val {
514493
fv.set_call_conventions(cconv)
515494
}
516495
let gv = fv.as_global_value();
517496
gv.set_linkage(DLLImport);
518497
var.comp_val = Some(gv.as_pointer_value().into());
519498
}
520-
return Ok(var);
499+
return var;
521500
}
522501
} else if let Some(t) = var
523502
.data_type
524503
.downcast::<types::Reference>()
525504
.and_then(|t| t.llvm_type(ctx))
526505
{
527-
let gv = ctx.module.add_global(
528-
t,
529-
None,
530-
std::str::from_utf8(comp_val).map_err(|_| {
531-
D::Error::invalid_value(de::Unexpected::Bytes(comp_val), &"a string")
532-
})?,
533-
);
506+
let gv = ctx.module.add_global(t, None, &comp_val);
534507
gv.set_linkage(DLLImport);
535508
var.comp_val = Some(gv.as_pointer_value().into());
536509
}
537-
Ok(var)
510+
var
538511
},
539512
)
540513
}

cobalt-ast/src/varmap.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ impl Serialize for Symbol<'_, '_> {
148148
fn skip_serializing_parent(p: &Option<Box<VarMap>>) -> bool {
149149
p.as_ref().map_or(true, |p| p.parent.is_none())
150150
}
151+
fn serialize_var_symbols<S: Serializer>(
152+
syms: &HashMap<Cow<str>, Symbol>,
153+
serializer: S,
154+
) -> Result<S::Ok, S::Error> {
155+
serializer.collect_map(syms.iter().filter(|v| v.1 .1.export))
156+
}
151157

152158
#[derive(Debug, Clone, Default, SerializeState, DeserializeState)]
153159
#[serde(crate = "serde_state")]
@@ -156,7 +162,7 @@ fn skip_serializing_parent(p: &Option<Box<VarMap>>) -> bool {
156162
pub struct VarMap<'src, 'ctx> {
157163
#[serde(deserialize_state, skip_serializing_if = "skip_serializing_parent")]
158164
pub parent: Option<Box<Self>>,
159-
#[serde(deserialize_state)]
165+
#[serde(deserialize_state, serialize_with = "serialize_var_symbols")]
160166
pub symbols: HashMap<Cow<'src, str>, Symbol<'src, 'ctx>>,
161167
pub imports: Vec<(CompoundDottedName<'src>, bool)>,
162168
}

0 commit comments

Comments
 (0)