forked from AbleOS/holey-bytes
fixing slice slicing
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
888b38ad4c
commit
939d0807fb
|
@ -798,6 +798,14 @@ main := fn(): uint {
|
|||
|
||||
### Purely Testing Examples
|
||||
|
||||
#### subsclice_bug
|
||||
```hb
|
||||
main := fn(): void {
|
||||
str := "abcd\0"
|
||||
@eca(37, str[1..].ptr)
|
||||
}
|
||||
```
|
||||
|
||||
#### proper_ident_propagation
|
||||
```hb
|
||||
A := fn($T: type): type return struct {a: T}
|
||||
|
|
|
@ -36,6 +36,9 @@ use {
|
|||
const DEFAULT_ACLASS: usize = 0;
|
||||
const GLOBAL_ACLASS: usize = 1;
|
||||
|
||||
const SLICE_PTR_OFF: Offset = 0;
|
||||
const SLICE_LEN_OFF: Offset = 8;
|
||||
|
||||
macro_rules! inference {
|
||||
($ty:ident, $ctx:expr, $self:expr, $pos:expr, $subject:literal, $example:literal) => {
|
||||
let Some($ty) = $ctx.ty else {
|
||||
|
@ -1273,7 +1276,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
ty::Kind::Slice(_) => {
|
||||
// Might change
|
||||
let off = self.offset(bs.id, 8);
|
||||
let off = self.offset(bs.id, SLICE_LEN_OFF);
|
||||
self.load_mem(off, ty::Id::UINT)
|
||||
}
|
||||
ty::Kind::Ptr(_) => {
|
||||
|
@ -1314,13 +1317,23 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
let ptr = self.offset_ptr(bs.id, elem, start);
|
||||
let ptr = match bs.ty.expand() {
|
||||
ty::Kind::Slice(s) if let Some(_) = self.tys.ins.slices[s].len() => bs,
|
||||
ty::Kind::Slice(_) => {
|
||||
// Might change
|
||||
let off = self.offset(bs.id, SLICE_PTR_OFF);
|
||||
let base = self.tys.make_ptr(elem);
|
||||
Value::new(self.load_mem(off, base)).ty(base)
|
||||
}
|
||||
ty::Kind::Ptr(_) => bs,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.ci.nodes.lock(ptr.id);
|
||||
|
||||
let ty = self.tys.make_array(elem, ArrayLen::MAX);
|
||||
|
||||
let mem = self.new_stack(pos, ty);
|
||||
for (off, value) in [(0u32, ptr), (8, len)] {
|
||||
for (off, value) in [(SLICE_PTR_OFF, ptr), (SLICE_LEN_OFF, len)] {
|
||||
let region = self.offset(mem, off);
|
||||
self.store_mem(region, value.ty, value.id);
|
||||
}
|
||||
|
@ -1347,7 +1360,7 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
ty::Kind::Slice(s) => {
|
||||
let elem = self.tys.ins.slices[s].elem;
|
||||
let off = self.offset(bs.id, 0);
|
||||
let off = self.offset(bs.id, SLICE_PTR_OFF);
|
||||
let base = self.tys.make_ptr(elem);
|
||||
let bs = self.load_mem(off, base);
|
||||
Some(self.offset_ptr(bs, elem, idx.id))
|
||||
|
@ -1438,7 +1451,9 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
let slc = self.tys.make_array(ty::Id::U8, ArrayLen::MAX);
|
||||
let mem = self.new_stack(pos, slc);
|
||||
for (off, value) in [(0u32, Value::ptr(global).ty(ty)), (8, len)] {
|
||||
for (off, value) in
|
||||
[(SLICE_PTR_OFF, Value::ptr(global).ty(ty)), (SLICE_LEN_OFF, len)]
|
||||
{
|
||||
let region = self.offset(mem, off);
|
||||
self.store_mem(region, value.ty, value.id);
|
||||
}
|
||||
|
@ -2063,22 +2078,24 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
let terminated = self.expr(body).is_none();
|
||||
|
||||
let Some(&Loop::Comptime { state, .. }) = self.ci.loops.last() else {
|
||||
let Some(Loop::Comptime { state, .. }) = self.ci.loops.last_mut() else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
if !terminated && let Some((_, prev)) = state {
|
||||
if !terminated && let Some((_, prev)) = *state {
|
||||
self.error(
|
||||
pos,
|
||||
"reached a constrol flow keyword inside an unrolled loop, \
|
||||
as well ast the end of the loop, make sure control flow is \
|
||||
as well as the end of the loop, make sure control flow is \
|
||||
not dependant on a runtime value",
|
||||
);
|
||||
return self.error(prev, "previous reachable control flow found here");
|
||||
}
|
||||
|
||||
match state {
|
||||
match state.take() {
|
||||
// loop never loops
|
||||
Some((CtLoopState::Terminated, _)) => break,
|
||||
// loop loops forever
|
||||
Some((CtLoopState::Continued, _)) | None => {}
|
||||
}
|
||||
}
|
||||
|
@ -2621,8 +2638,8 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
ty::Kind::Slice(s) => {
|
||||
let (offset, ty) = match name {
|
||||
"len" => (8, ty::Id::UINT),
|
||||
"ptr" => (0, self.tys.make_ptr(self.tys.ins.slices[s].elem)),
|
||||
"len" => (SLICE_LEN_OFF, ty::Id::UINT),
|
||||
"ptr" => (SLICE_PTR_OFF, self.tys.make_ptr(self.tys.ins.slices[s].elem)),
|
||||
_ => return None,
|
||||
};
|
||||
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
|
||||
|
@ -4367,7 +4384,7 @@ mod tests {
|
|||
fn generate(ident: &'static str, input: &'static str, output: &mut String) {
|
||||
_ = log::set_logger(&crate::fs::Logger);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
//log::set_max_level(log::LevelFilter::Trace);
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
|
||||
let mut ctx = CodegenCtx::default();
|
||||
let (ref files, embeds) = crate::test_parse_files(ident, input, &mut ctx.parser);
|
||||
|
@ -4437,6 +4454,7 @@ mod tests {
|
|||
fb_driver;
|
||||
|
||||
// Purely Testing Examples;
|
||||
subsclice_bug;
|
||||
string_array;
|
||||
proper_ident_propagation;
|
||||
method_receiver_by_value;
|
||||
|
|
0
lang/tests/son_tests_subsclice_bug.txt
Normal file
0
lang/tests/son_tests_subsclice_bug.txt
Normal file
Loading…
Reference in a new issue