Skip to content

Commit 4c56b60

Browse files
committed
Add (nonfunctional) LoxString
remove big files
1 parent 6134c80 commit 4c56b60

File tree

9 files changed

+209
-19
lines changed

9 files changed

+209
-19
lines changed

lox-gc/src/heap.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::cell::Cell;
22

3-
/*
43
struct MemoryMap {
4+
size: usize,
55
data: *mut u8,
66
}
77

@@ -12,6 +12,7 @@ impl MemoryMap {
1212
let data = std::alloc::alloc(layout);
1313

1414
Self {
15+
size,
1516
data,
1617
}
1718
}
@@ -21,7 +22,15 @@ impl MemoryMap {
2122
self.data
2223
}
2324
}
24-
*/
25+
26+
impl Drop for MemoryMap {
27+
fn drop(&mut self) {
28+
let layout = std::alloc::Layout::array::<u8>(self.size).unwrap().align_to(4096).unwrap();
29+
unsafe {
30+
std::alloc::dealloc(self.data, layout);
31+
}
32+
}
33+
}
2534

2635
/// Returns the number of pages needed for `n` bytes (rounding up).
2736
const fn bytes_to_pages(n: usize) -> usize {
@@ -37,17 +46,18 @@ const fn bytes_to_pages(n: usize) -> usize {
3746
struct PdIdx(u32);
3847

3948
struct AddrSpace {
40-
mem: mmap::MemoryMap,
49+
//mem: mmap::MemoryMap,
50+
mem: MemoryMap,
4151

4252
used_pds: Cell<u32>,
4353
}
4454

4555
impl AddrSpace {
4656
const PAGE_BYTES: usize = 4096;
4757

48-
const DATA_BYTES: usize = 4 * 1024 * 1024 * 1024; // 4G
58+
//const DATA_BYTES: usize = 4 * 1024 * 1024 * 1024; // 4G
4959
//const DATA_BYTES: usize = 64 * 1024 * 1024; // 64MB
50-
//const DATA_BYTES: usize = 32 * 1024 * 1024; // 32MB
60+
const DATA_BYTES: usize = 32 * 1024 * 1024; // 32MB
5161
const DATA_PAGES: usize = Self::DATA_BYTES / Self::PAGE_BYTES;
5262

5363
const PD_PAGES: usize = bytes_to_pages(Self::DATA_PAGES * std::mem::size_of::<PageDescriptor>());
@@ -63,9 +73,10 @@ impl AddrSpace {
6373

6474
/// Constructs a new [`AddrSpace`]. This will return `None` on error.
6575
pub fn create() -> Option<Self> {
66-
use mmap::*;
76+
//use mmap::*;
6777

68-
let mem = MemoryMap::new(Self::TOTAL_BYTES, &[MapOption::MapReadable, MapOption::MapWritable]).ok()?;
78+
//let mem = MemoryMap::new(Self::TOTAL_BYTES, &[MapOption::MapReadable, MapOption::MapWritable]).ok()?;
79+
let mem = self::MemoryMap::new(Self::TOTAL_BYTES);
6980

7081
Some(Self {
7182
mem,
@@ -659,8 +670,8 @@ impl Heap {
659670
},
660671
};
661672

662-
//println!("page {:?}", page.idx);
663673
let index = page.take_next_block().expect("Full page in free list");
674+
//println!("page {:?} {:?} {} {:?}", size_class, page.idx, index, size_class.block_bytes());
664675

665676
if page.is_full() {
666677
//println!("full {:?}", page.idx);

lox-vm/src/array.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,30 @@ impl<T> Array<T> where T: Copy {
4343
}
4444
}
4545

46+
impl<T> Array<T> where T: Clone {
47+
//TODO rewrite.
48+
pub fn extend_from_slice(&mut self, other: &[T]) {
49+
for elem in other {
50+
self.push(elem.clone());
51+
}
52+
}
53+
}
54+
55+
impl<T> Clone for Array<T> {
56+
fn clone(&self) -> Self {
57+
unsafe {
58+
let ptr = lox_gc::alloc(std::alloc::Layout::array::<T>(self.cap).unwrap()) as *mut T;
59+
std::ptr::copy_nonoverlapping(self.ptr.as_ptr(), ptr, self.cap);
60+
61+
Self {
62+
cap: self.cap,
63+
len: self.len,
64+
ptr: NonNull::new_unchecked(ptr),
65+
}
66+
}
67+
}
68+
}
69+
4670
impl<T> Array<T> {
4771
pub fn new() -> Self {
4872
assert!(mem::size_of::<T>() != 0, "must not be ZST");
@@ -127,15 +151,20 @@ impl<T> Array<T> {
127151
assert!(new_layout.size() <= isize::MAX as usize, "Allocation too large");
128152

129153
let new_ptr = if self.cap == 0 {
130-
unsafe { lox_gc::alloc(new_layout) }
154+
let new_ptr = unsafe { lox_gc::alloc(new_layout) };
155+
dbg!(new_layout, new_ptr);
156+
new_ptr
131157
} else {
132158
//TODO We copy more than we need to.
133159
let old_layout = Layout::array::<T>(self.cap).unwrap();
134160
let old_ptr = self.ptr.as_ptr() as *mut u8;
135161
let new_ptr = unsafe { lox_gc::alloc(new_layout) };
162+
dbg!(new_layout, old_layout.size(), old_ptr, new_ptr);
163+
136164
unsafe {
137-
ptr::copy_nonoverlapping(old_ptr, new_ptr, old_layout.size());
165+
ptr::copy(old_ptr, new_ptr, old_layout.size());
138166
}
167+
139168
new_ptr
140169
};
141170

lox-vm/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ mod stack;
1212
mod ops;
1313
mod fiber;
1414
mod table;
15+
16+
//TODO Move to lox-gc
1517
mod array;
18+
mod string;
1619

1720
use lox_bytecode::bytecode::Module;
1821
use runtime::Runtime;

lox-vm/src/memory.rs

+4
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ pub use class::*;
1616
pub use native_function::*;
1717
pub use bound_method::*;
1818

19+
use crate::string::LoxString;
20+
1921
pub fn print(value: crate::gc::Gc<()>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2022
if value.is::<String>() {
2123
write!(f, "{}", value.cast::<String>().as_str())
24+
} else if value.is::<LoxString>() {
25+
write!(f, "{}", value.cast::<LoxString>().as_str())
2226
} else if value.is::<Closure>() {
2327
write!(f, "<fn {}>", value.cast::<Closure>().function.name)
2428
} else if value.is::<BoundMethod>() {

lox-vm/src/memory/import.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ use lox_bytecode::bytecode;
66
use crate::table::Table;
77
use crate::value::Value;
88
use crate::array::Array;
9+
use crate::string::LoxString;
910

1011
pub struct Import {
1112
pub name: String,
1213
module: Module,
1314
globals: UnsafeCell<Table>,
1415
symbols: Array<Symbol>,
15-
strings: Array<Gc<String>>,
16+
strings: Array<Gc<LoxString>>,
1617
}
1718

1819
unsafe impl Trace for Import {
@@ -40,10 +41,15 @@ impl Import {
4041
interner.intern(identifier)
4142
}).collect();
4243

43-
let strings = module.strings.iter().map(|value| {
44-
lox_gc::manage(value.clone().into())
44+
println!("HERE");
45+
let strings: Array<Gc<LoxString>> = module.strings.iter().map(|value| {
46+
lox_gc::manage(value.into())
4547
}).collect();
4648

49+
for value in strings.iter() {
50+
println!("STR {}", value);
51+
}
52+
4753
Self {
4854
name: name.into(),
4955
module,
@@ -81,7 +87,7 @@ impl Import {
8187
}
8288

8389
#[inline]
84-
pub(crate) fn string(&self, index: ConstantIndex) -> Gc<String> {
90+
pub(crate) fn string(&self, index: ConstantIndex) -> Gc<LoxString> {
8591
unsafe {
8692
*self.strings.get_unchecked(index)
8793
}

lox-vm/src/runtime.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use super::memory::*;
88
use super::interner::{Symbol, Interner};
99
use super::gc::{Gc, Trace, Tracer};
1010
use crate::fiber::Fiber;
11+
use crate::string::LoxString;
1112
use std::collections::HashMap;
1213

1314
#[derive(PartialEq, Eq, Copy, Clone)]
@@ -119,9 +120,9 @@ impl Runtime {
119120

120121
#[cold]
121122
pub fn concat(&self, a: Value, b: Value) -> Signal {
122-
if a.is_object_of_type::<String>() && b.is_object_of_type::<String>() {
123-
let a = a.as_object().cast::<String>();
124-
let b = b.as_object().cast::<String>();
123+
if a.is_object_of_type::<LoxString>() && b.is_object_of_type::<LoxString>() {
124+
let a = a.as_object().cast::<LoxString>();
125+
let b = b.as_object().cast::<LoxString>();
125126
self.push_string(format!("{}{}", a.as_str(), b.as_str()));
126127
return Signal::More;
127128
}
@@ -248,9 +249,9 @@ impl Runtime {
248249
}
249250

250251
#[cold]
251-
pub fn push_string(&self, string: impl Into<String>) {
252+
pub fn push_string(&self, string: impl Into<LoxString>) {
252253
let string = string.into();
253-
let root: Gc<String> = self.manage(string.into());
254+
let root: Gc<LoxString> = self.manage(string);
254255
self.fiber.with_stack(|stack| {
255256
stack.push(Value::from_object(root.erase()));
256257
});

lox-vm/src/string.rs

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use crate::array::Array;
2+
use std::ops::{Deref, DerefMut};
3+
use std::str;
4+
use std::borrow::{Borrow, BorrowMut};
5+
use std::fmt;
6+
use std::hash::Hash;
7+
use lox_gc::{Trace, Tracer};
8+
9+
pub struct LoxString {
10+
vec: Array<u8>,
11+
}
12+
13+
impl LoxString {
14+
pub fn new() -> Self {
15+
Self {
16+
vec: Array::new(),
17+
}
18+
}
19+
20+
pub fn as_bytes(&self) -> &[u8] {
21+
&self.vec
22+
}
23+
24+
pub fn with_capacity(capacity: usize) -> Self {
25+
Self {
26+
vec: Array::with_capacity(capacity),
27+
}
28+
}
29+
30+
pub fn as_str(&self) -> &str {
31+
self
32+
}
33+
34+
pub fn push_str(&mut self, string: &str) {
35+
self.vec.extend_from_slice(string.as_bytes());
36+
}
37+
}
38+
39+
unsafe impl Trace for LoxString {
40+
fn trace(&self, _tracer: &mut Tracer) {
41+
self.vec.mark();
42+
}
43+
}
44+
45+
impl PartialEq<LoxString> for LoxString {
46+
fn eq(&self, other: &LoxString) -> bool {
47+
PartialEq::eq(&self[..], &other[..])
48+
}
49+
50+
fn ne(&self, other: &LoxString) -> bool {
51+
PartialEq::ne(&self[..], &other[..])
52+
}
53+
}
54+
55+
impl From<String> for LoxString {
56+
fn from(value: String) -> Self {
57+
let mut str = LoxString::with_capacity(value.len());
58+
str.push_str(&value);
59+
str
60+
}
61+
}
62+
63+
impl From<&String> for LoxString {
64+
fn from(value: &String) -> Self {
65+
let mut str = LoxString::with_capacity(value.len());
66+
str.push_str(value);
67+
str
68+
}
69+
}
70+
71+
impl fmt::Debug for LoxString {
72+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73+
fmt::Debug::fmt(&**self, f)
74+
}
75+
}
76+
77+
impl fmt::Display for LoxString {
78+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79+
fmt::Display::fmt(&**self, f)
80+
}
81+
}
82+
83+
impl Hash for LoxString {
84+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
85+
(&**self).hash(state)
86+
}
87+
}
88+
89+
impl Default for LoxString {
90+
fn default() -> Self {
91+
Self::new()
92+
}
93+
}
94+
95+
impl Deref for LoxString {
96+
type Target = str;
97+
98+
fn deref(&self) -> &Self::Target {
99+
unsafe { str::from_utf8_unchecked(&self.vec) }
100+
}
101+
}
102+
103+
impl DerefMut for LoxString {
104+
fn deref_mut(&mut self) -> &mut Self::Target {
105+
unsafe { str::from_utf8_unchecked_mut(&mut self.vec) }
106+
}
107+
}
108+
109+
impl AsRef<str> for LoxString {
110+
fn as_ref(&self) -> &str {
111+
self
112+
}
113+
}
114+
115+
impl Borrow<str> for LoxString {
116+
fn borrow(&self) -> &str {
117+
&self[..]
118+
}
119+
}
120+
121+
impl BorrowMut<str> for LoxString {
122+
fn borrow_mut(&mut self) -> &mut str {
123+
&mut self[..]
124+
}
125+
}
126+
127+
impl AsRef<[u8]> for LoxString {
128+
fn as_ref(&self) -> &[u8] {
129+
self.as_bytes()
130+
}
131+
}

lox-vm/src/value.rs

+4
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,12 @@ impl From<bool> for Value {
122122
impl PartialEq for Value {
123123
#[inline]
124124
fn eq(&self, other: &Self) -> bool {
125+
use crate::string::LoxString;
126+
125127
if self.is_number() && other.is_number() {
126128
self.as_number() == other.as_number()
129+
} else if self.is_object_of_type::<LoxString>() && other.is_object_of_type::<LoxString>() {
130+
&*self.as_object().cast::<LoxString>() == &*other.as_object().cast::<LoxString>()
127131
} else if self.is_object() && other.is_object() {
128132
self.as_object() == other.as_object()
129133
} else {

simple.lox

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
print "a" + "b";
2+
print "a"+"b" == "a"+"b";

0 commit comments

Comments
 (0)