Skip to content
This repository was archived by the owner on May 29, 2025. It is now read-only.

Commit 3b512e5

Browse files
committed
add rust-pack for building fake std
1 parent f0b29a3 commit 3b512e5

File tree

16 files changed

+274
-343449
lines changed

16 files changed

+274
-343449
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/.bundle
22
/vendor
3-
/target
3+
target
44
/_site
55
.sass-cache
66
.jekyll-cache

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
To run:
44

55
```shell
6+
$ cd rust-pack
7+
$ cargo run
8+
$ cd ../ra-wasm
69
$ wasm-pack build --target web
7-
$ cd www
10+
$ cd ../www
811
$ yarn
912
$ yarn start
1013
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

rust-pack/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust-pack/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "rust-pack"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[[bin]]
7+
name = "rust-pack"
8+
9+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10+
11+
[dependencies]

rust-pack/src/main.rs

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#![feature(str_split_once)]
2+
3+
use core::panic;
4+
use std::fs;
5+
use std::fs::read_to_string;
6+
use std::path::Path;
7+
use std::process::Command;
8+
9+
mod remove_function;
10+
11+
//use remove_function::remove_function_body;
12+
13+
struct Mod<'a> {
14+
pub_prefix: &'a str,
15+
explicit_path: Option<&'a str>,
16+
name: &'a str,
17+
}
18+
19+
#[derive(Default, Debug)]
20+
struct ModState<'a> {
21+
path_seen: Option<&'a str>,
22+
in_attribute: bool,
23+
}
24+
25+
fn remove_comment<'a>(line: &'a str) -> &'a str {
26+
if let Some((l, _)) = line.split_once("//") {
27+
l.trim()
28+
} else {
29+
line
30+
}
31+
}
32+
33+
fn clean_token<'a>(line: &'a str) -> &'a str {
34+
if let Some(l) = line.strip_prefix("r#") {
35+
l
36+
} else {
37+
line
38+
}
39+
}
40+
41+
fn is_external_mod<'a>(mod_state: &mut ModState<'a>, line: &'a str) -> Option<Mod<'a>> {
42+
let line = remove_comment(line);
43+
if line.is_empty() {
44+
return None;
45+
}
46+
if line.starts_with("#[path = ") {
47+
mod_state.path_seen = Some(&line[10..line.len() - 2]);
48+
return None;
49+
}
50+
if line.starts_with("#[") {
51+
if !line.ends_with(']') {
52+
mod_state.in_attribute = true;
53+
}
54+
return None;
55+
}
56+
if mod_state.in_attribute {
57+
if line.ends_with(']') {
58+
mod_state.in_attribute = false;
59+
}
60+
return None;
61+
}
62+
let current_mod_state = std::mem::take(mod_state);
63+
if !line.ends_with(';') {
64+
return None;
65+
}
66+
let line = &line[..line.len() - 1];
67+
if let Some(line) = line.strip_prefix("mod ") {
68+
Some(Mod {
69+
explicit_path: current_mod_state.path_seen,
70+
pub_prefix: "",
71+
name: clean_token(line),
72+
})
73+
} else if let Some(line) = line.strip_prefix("pub mod ") {
74+
Some(Mod {
75+
explicit_path: current_mod_state.path_seen,
76+
pub_prefix: "pub ",
77+
name: clean_token(line),
78+
})
79+
} else if let Some(line) = line.strip_prefix("pub(crate) mod ") {
80+
Some(Mod {
81+
explicit_path: current_mod_state.path_seen,
82+
pub_prefix: "pub(crate) ",
83+
name: clean_token(line),
84+
})
85+
} else if let Some(line) = line.strip_prefix("pub(self) mod ") {
86+
Some(Mod {
87+
explicit_path: current_mod_state.path_seen,
88+
pub_prefix: "pub(self) ",
89+
name: clean_token(line),
90+
})
91+
} else if let Some(line) = line.strip_prefix("pub(super) mod ") {
92+
Some(Mod {
93+
explicit_path: current_mod_state.path_seen,
94+
pub_prefix: "pub(super) ",
95+
name: clean_token(line),
96+
})
97+
} else if let Some(line) = line.strip_prefix("pub(in ") {
98+
panic!("pub in not supported: {}", line);
99+
} else {
100+
None
101+
}
102+
}
103+
104+
trait MyStringMethods {
105+
fn push_line(&mut self, line: &str);
106+
}
107+
108+
impl MyStringMethods for String {
109+
fn push_line(&mut self, line: &str) {
110+
self.push_str(line);
111+
self.push('\n');
112+
}
113+
}
114+
115+
#[derive(Default, Debug)]
116+
struct MyError {
117+
libstack: Vec<String>,
118+
cause_module: String,
119+
}
120+
121+
fn put_module_in_string(
122+
output: &mut String,
123+
path: &Path,
124+
depth: usize,
125+
mut expand_cnt: i32,
126+
) -> Result<(), MyError> {
127+
let src = read_to_string(path).map_err(|_x| MyError {
128+
libstack: vec![],
129+
cause_module: path.to_string_lossy().to_string(),
130+
})?;
131+
let mut mod_state = ModState::default();
132+
for line in src.lines() {
133+
//println!("mod State: {:#?}", mod_state);
134+
if let Some(m) = is_external_mod(&mut mod_state, line) {
135+
if expand_cnt == 0 {
136+
continue;
137+
};
138+
let rr = 10000;
139+
// if m.name == "try_trait" || m.name == "unsize" {
140+
// continue;
141+
//}
142+
expand_cnt -= 1;
143+
println!("{} mod found: {}", ">".repeat(depth), line);
144+
output.push_line(&format!("{}mod {} {{", m.pub_prefix, m.name));
145+
let mut parent_path = path.parent().unwrap().to_owned();
146+
let file_name =
147+
path.file_name().unwrap().to_str().unwrap().strip_suffix(".rs").unwrap();
148+
if file_name != "lib" && file_name != "mod" {
149+
parent_path = parent_path.join(file_name);
150+
}
151+
let same_level_path = parent_path.join(format!("{}.rs", m.name));
152+
let folder_path = parent_path.join(format!("{}/mod.rs", m.name));
153+
let child_path = if let Some(ep) = m.explicit_path {
154+
println!("explicit path found: {:?}", ep);
155+
parent_path.join(ep)
156+
} else if same_level_path.exists() {
157+
same_level_path
158+
} else if folder_path.exists() {
159+
folder_path
160+
} else {
161+
println!(
162+
"same_level_path: {:?}\nfolder_path: {:?}\n",
163+
same_level_path, folder_path
164+
);
165+
return Err(MyError {
166+
libstack: vec![path.to_string_lossy().to_string()],
167+
cause_module: folder_path.to_string_lossy().to_string(),
168+
});
169+
};
170+
if let Err(mut e) = put_module_in_string(output, &child_path, depth + 1, rr) {
171+
e.libstack.push(path.to_string_lossy().to_string());
172+
return Err(e);
173+
}
174+
output.push_line("}");
175+
} else {
176+
output.push_line(line);
177+
}
178+
}
179+
Ok(())
180+
}
181+
182+
fn main() {
183+
let rustc_result = Command::new("rustc")
184+
.args(&["--print", "sysroot"])
185+
.output()
186+
.expect("Failed to execute rustc")
187+
.stdout;
188+
let sysroot = std::str::from_utf8(&rustc_result).expect("rustc output wasn't utf8");
189+
for what in &["std", "alloc", "core"] {
190+
let path_string = &format!("{}/lib/rustlib/src/rust/library/{}/src/lib.rs", sysroot.trim(), what);
191+
let path = Path::new(&path_string);
192+
let output_path = format!("../www/fake_{}.rs", what);
193+
let mut output = String::default();
194+
put_module_in_string(&mut output, path, 0, 4000).unwrap();
195+
//output = remove_function_body(&output);
196+
fs::write(output_path, output.clone()).unwrap();
197+
}
198+
}

rust-pack/src/remove_function.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
fn pick_char(input: &mut &str) -> char {
3+
let mut iter = input.chars();
4+
let r = iter.next().unwrap();
5+
*input = iter.as_str();
6+
r
7+
}
8+
9+
fn eat_until(input: &mut &str, output: &mut String, goal: char) {
10+
let mut paran = if goal == 'x' { 2 } else { 0 };
11+
while input.len() > 0 {
12+
let c = input.chars().next().unwrap();
13+
if paran > 0 {
14+
if c == ')' || c == ']' || c == '}' {
15+
paran -= 1;
16+
}
17+
} else {
18+
if c == goal || goal == 'x' {
19+
return;
20+
}
21+
if c == '(' || c == '[' || c == '{' {
22+
paran += 1;
23+
}
24+
}
25+
pick_char(input);
26+
output.push(c);
27+
}
28+
}
29+
30+
pub fn remove_function_body(mut input: &str) -> String {
31+
let mut output = String::new();
32+
let mut char_seened = 'x';
33+
while input.len() > 0 {
34+
if char_seened.is_whitespace() {
35+
if let Some(remain) = input.strip_prefix("fn ") {
36+
output.push_str("fn ");
37+
input = remain;
38+
eat_until(&mut input, &mut output, '{');
39+
output.push_str("{ loop {} }");
40+
eat_until(&mut input, &mut String::new(), 'x');
41+
}
42+
}
43+
if input.starts_with("//") {
44+
let (comment, remain) = input.split_once("\n").unwrap();
45+
output.push_str(comment);
46+
input = remain;
47+
}
48+
char_seened = pick_char(&mut input);
49+
output.push(char_seened);
50+
}
51+
output
52+
}

0 commit comments

Comments
 (0)