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
|
### Purely Testing Examples
|
||||||
|
|
||||||
|
#### subsclice_bug
|
||||||
|
```hb
|
||||||
|
main := fn(): void {
|
||||||
|
str := "abcd\0"
|
||||||
|
@eca(37, str[1..].ptr)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### proper_ident_propagation
|
#### proper_ident_propagation
|
||||||
```hb
|
```hb
|
||||||
A := fn($T: type): type return struct {a: T}
|
A := fn($T: type): type return struct {a: T}
|
||||||
|
|
|
@ -36,6 +36,9 @@ use {
|
||||||
const DEFAULT_ACLASS: usize = 0;
|
const DEFAULT_ACLASS: usize = 0;
|
||||||
const GLOBAL_ACLASS: usize = 1;
|
const GLOBAL_ACLASS: usize = 1;
|
||||||
|
|
||||||
|
const SLICE_PTR_OFF: Offset = 0;
|
||||||
|
const SLICE_LEN_OFF: Offset = 8;
|
||||||
|
|
||||||
macro_rules! inference {
|
macro_rules! inference {
|
||||||
($ty:ident, $ctx:expr, $self:expr, $pos:expr, $subject:literal, $example:literal) => {
|
($ty:ident, $ctx:expr, $self:expr, $pos:expr, $subject:literal, $example:literal) => {
|
||||||
let Some($ty) = $ctx.ty else {
|
let Some($ty) = $ctx.ty else {
|
||||||
|
@ -1273,7 +1276,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
ty::Kind::Slice(_) => {
|
ty::Kind::Slice(_) => {
|
||||||
// Might change
|
// 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)
|
self.load_mem(off, ty::Id::UINT)
|
||||||
}
|
}
|
||||||
ty::Kind::Ptr(_) => {
|
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);
|
self.ci.nodes.lock(ptr.id);
|
||||||
|
|
||||||
let ty = self.tys.make_array(elem, ArrayLen::MAX);
|
let ty = self.tys.make_array(elem, ArrayLen::MAX);
|
||||||
|
|
||||||
let mem = self.new_stack(pos, ty);
|
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);
|
let region = self.offset(mem, off);
|
||||||
self.store_mem(region, value.ty, value.id);
|
self.store_mem(region, value.ty, value.id);
|
||||||
}
|
}
|
||||||
|
@ -1347,7 +1360,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
ty::Kind::Slice(s) => {
|
ty::Kind::Slice(s) => {
|
||||||
let elem = self.tys.ins.slices[s].elem;
|
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 base = self.tys.make_ptr(elem);
|
||||||
let bs = self.load_mem(off, base);
|
let bs = self.load_mem(off, base);
|
||||||
Some(self.offset_ptr(bs, elem, idx.id))
|
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 slc = self.tys.make_array(ty::Id::U8, ArrayLen::MAX);
|
||||||
let mem = self.new_stack(pos, slc);
|
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);
|
let region = self.offset(mem, off);
|
||||||
self.store_mem(region, value.ty, value.id);
|
self.store_mem(region, value.ty, value.id);
|
||||||
}
|
}
|
||||||
|
@ -2063,22 +2078,24 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let terminated = self.expr(body).is_none();
|
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!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
if !terminated && let Some((_, prev)) = state {
|
if !terminated && let Some((_, prev)) = *state {
|
||||||
self.error(
|
self.error(
|
||||||
pos,
|
pos,
|
||||||
"reached a constrol flow keyword inside an unrolled loop, \
|
"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",
|
not dependant on a runtime value",
|
||||||
);
|
);
|
||||||
return self.error(prev, "previous reachable control flow found here");
|
return self.error(prev, "previous reachable control flow found here");
|
||||||
}
|
}
|
||||||
|
|
||||||
match state {
|
match state.take() {
|
||||||
|
// loop never loops
|
||||||
Some((CtLoopState::Terminated, _)) => break,
|
Some((CtLoopState::Terminated, _)) => break,
|
||||||
|
// loop loops forever
|
||||||
Some((CtLoopState::Continued, _)) | None => {}
|
Some((CtLoopState::Continued, _)) | None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2621,8 +2638,8 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
ty::Kind::Slice(s) => {
|
ty::Kind::Slice(s) => {
|
||||||
let (offset, ty) = match name {
|
let (offset, ty) = match name {
|
||||||
"len" => (8, ty::Id::UINT),
|
"len" => (SLICE_LEN_OFF, ty::Id::UINT),
|
||||||
"ptr" => (0, self.tys.make_ptr(self.tys.ins.slices[s].elem)),
|
"ptr" => (SLICE_PTR_OFF, self.tys.make_ptr(self.tys.ins.slices[s].elem)),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
|
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) {
|
fn generate(ident: &'static str, input: &'static str, output: &mut String) {
|
||||||
_ = log::set_logger(&crate::fs::Logger);
|
_ = log::set_logger(&crate::fs::Logger);
|
||||||
log::set_max_level(log::LevelFilter::Info);
|
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 mut ctx = CodegenCtx::default();
|
||||||
let (ref files, embeds) = crate::test_parse_files(ident, input, &mut ctx.parser);
|
let (ref files, embeds) = crate::test_parse_files(ident, input, &mut ctx.parser);
|
||||||
|
@ -4437,6 +4454,7 @@ mod tests {
|
||||||
fb_driver;
|
fb_driver;
|
||||||
|
|
||||||
// Purely Testing Examples;
|
// Purely Testing Examples;
|
||||||
|
subsclice_bug;
|
||||||
string_array;
|
string_array;
|
||||||
proper_ident_propagation;
|
proper_ident_propagation;
|
||||||
method_receiver_by_value;
|
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