Skip to content

Commit 737054e

Browse files
committed
Some backend experiments. More work on fixing unsizing. Added suppoirt for creaing tests
1 parent 1115270 commit 737054e

File tree

16 files changed

+897
-187
lines changed

16 files changed

+897
-187
lines changed

.github/workflows/rust.yml

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
run: cargo build --verbose
2525
linux_test:
2626
runs-on: ubuntu-latest
27+
env:
28+
NEW_UNSIZE: 1
2729
steps:
2830
- uses: actions/checkout@v3
2931
- name: Build

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rustc-demangle = "0.1.23"
2020
cilly = {path = "./cilly"}
2121
serde = { version = "1.0.183", features = ["derive"] }
2222
strsim = "0.11.1"
23+
regex = "1.10.5"
2324

2425
[lib]
2526
crate-type=["rlib", "cdylib"]

build_all.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
cd cilly && cargo build --all --release && cargo build --all && cd .. && cargo build && cargo build --release

cilly/src/bin/linker/dotnet_jumpstart.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,5 @@ fn main(){{
5454
}}
5555
let args:Vec<String> = std::env::args().collect();
5656
let args = &args[1..];
57-
println!("std args:{{args:?}}");
58-
std::process::Command::new("dotnet").arg(dll_path).args(args).status().expect("Could not start the .NET runtime.");
59-
}}
57+
std::process::Command::new("{jumpstart_cmd}").arg(dll_path).args(args).status().expect("Could not start the .NET runtime.");
58+
}}

cilly/src/bin/linker/main.rs

+112-55
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use cilly::{
1111
cil_root::CILRoot,
1212
conv_usize,
1313
ilasm_exporter::ILASM_FLAVOUR,
14+
js_exporter::JSExporter,
1415
ldc_i32,
1516
method::{Method, MethodType},
1617
DotnetTypeRef, FnSig, IString, IlasmFlavour, Type,
@@ -24,7 +25,7 @@ mod export;
2425
use cilly::libc_fns;
2526
mod load;
2627
mod patch;
27-
use std::{collections::HashMap, env, io::Write};
28+
use std::{collections::HashMap, env, io::Write, path::Path};
2829
struct NativePastroughInfo {
2930
defs: HashMap<IString, IString>,
3031
}
@@ -771,67 +772,112 @@ fn main() {
771772
false,
772773
)
773774
.unwrap();
774-
return;
775-
}
776-
777-
// Run ILASM
778-
export::export_assembly(&final_assembly, output_file_path, is_lib)
775+
} else if *JS_MODE {
776+
type Exporter = cilly::js_exporter::JSExporter;
777+
use cilly::asm_exporter::AssemblyExporter;
778+
Exporter::export_assembly(
779+
Exporter::default(),
780+
&final_assembly,
781+
output_file_path.as_ref(),
782+
is_lib,
783+
false,
784+
)
779785
.expect("Assembly export faliure!");
780-
let path: std::path::PathBuf = output_file_path.into();
781-
final_assembly
782-
.save_tmp(&mut std::fs::File::create(path.with_extension("cilly")).unwrap())
783-
.unwrap();
784-
// Run AOT compiler
785-
aot_compile_mode.compile(output_file_path);
786+
let path: std::path::PathBuf = output_file_path.into();
787+
final_assembly
788+
.save_tmp(&mut std::fs::File::create(path.with_extension("cilly")).unwrap())
789+
.unwrap();
790+
// Run AOT compiler
791+
aot_compile_mode.compile(output_file_path);
786792

787-
// Cargo integration
793+
// Cargo integration
788794

789-
if cargo_support {
790-
let bootstrap = format!(
791-
include_str!("dotnet_jumpstart.rs"),
792-
exec_file = path.file_name().unwrap().to_string_lossy(),
793-
has_native_companion = *NATIVE_PASSTROUGH,
794-
has_pdb = match *ILASM_FLAVOUR {
795-
IlasmFlavour::Clasic => false,
796-
IlasmFlavour::Modern => true,
797-
},
798-
pdb_file = match *ILASM_FLAVOUR {
799-
IlasmFlavour::Clasic => String::new(),
800-
IlasmFlavour::Modern => format!(
801-
"{output_file_path}.pdb",
802-
output_file_path = path.file_name().unwrap().to_string_lossy()
803-
),
804-
},
805-
native_companion_file = if *NATIVE_PASSTROUGH {
806-
format!(
807-
"rust_native_{output_file_path}.so",
808-
output_file_path = file_stem(output_file_path)
809-
)
810-
} else {
811-
String::new()
812-
}
813-
);
814-
let bootstrap_path = path.with_extension("rs");
815-
let mut bootstrap_file = std::fs::File::create(&bootstrap_path).unwrap();
816-
bootstrap_file.write_all(bootstrap.as_bytes()).unwrap();
817-
let path = std::env::var("PATH").unwrap();
818-
let out = std::process::Command::new("rustc")
819-
.arg("-O")
820-
.arg(bootstrap_path)
821-
.arg("-o")
822-
.arg(output_file_path)
823-
.env_clear()
824-
.env("PATH", path)
825-
.output()
795+
if cargo_support {
796+
let bootstrap = bootstrap_source(&path, output_file_path, "node");
797+
let bootstrap_path = path.with_extension("rs");
798+
let mut bootstrap_file = std::fs::File::create(&bootstrap_path).unwrap();
799+
bootstrap_file.write_all(bootstrap.as_bytes()).unwrap();
800+
let path = std::env::var("PATH").unwrap();
801+
let out = std::process::Command::new("rustc")
802+
.arg("-O")
803+
.arg(bootstrap_path)
804+
.arg("-o")
805+
.arg(output_file_path)
806+
.env_clear()
807+
.env("PATH", path)
808+
.output()
809+
.unwrap();
810+
assert!(
811+
out.stderr.is_empty(),
812+
"{}",
813+
String::from_utf8(out.stderr).unwrap()
814+
);
815+
}
816+
} else {
817+
// Run ILASM
818+
export::export_assembly(&final_assembly, output_file_path, is_lib)
819+
.expect("Assembly export faliure!");
820+
let path: std::path::PathBuf = output_file_path.into();
821+
final_assembly
822+
.save_tmp(&mut std::fs::File::create(path.with_extension("cilly")).unwrap())
826823
.unwrap();
827-
assert!(
828-
out.stderr.is_empty(),
829-
"{}",
830-
String::from_utf8(out.stderr).unwrap()
831-
);
824+
// Run AOT compiler
825+
aot_compile_mode.compile(output_file_path);
826+
827+
// Cargo integration
828+
829+
if cargo_support {
830+
let bootstrap = bootstrap_source(&path, output_file_path, "dotnet");
831+
let bootstrap_path = path.with_extension("rs");
832+
let mut bootstrap_file = std::fs::File::create(&bootstrap_path).unwrap();
833+
bootstrap_file.write_all(bootstrap.as_bytes()).unwrap();
834+
let path = std::env::var("PATH").unwrap();
835+
let out = std::process::Command::new("rustc")
836+
.arg("-O")
837+
.arg(bootstrap_path)
838+
.arg("-o")
839+
.arg(output_file_path)
840+
.env_clear()
841+
.env("PATH", path)
842+
.output()
843+
.unwrap();
844+
assert!(
845+
out.stderr.is_empty(),
846+
"{}",
847+
String::from_utf8(out.stderr).unwrap()
848+
);
849+
}
832850
}
851+
833852
//todo!();
834853
}
854+
fn bootstrap_source(fpath: &Path, output_file_path: &str, jumpstart_cmd: &str) -> String {
855+
format!(
856+
include_str!("dotnet_jumpstart.rs"),
857+
jumpstart_cmd = "dotnet",
858+
exec_file = fpath.file_name().unwrap().to_string_lossy(),
859+
has_native_companion = *NATIVE_PASSTROUGH,
860+
has_pdb = match *ILASM_FLAVOUR {
861+
IlasmFlavour::Clasic => false,
862+
IlasmFlavour::Modern => true,
863+
},
864+
pdb_file = match *ILASM_FLAVOUR {
865+
IlasmFlavour::Clasic => String::new(),
866+
IlasmFlavour::Modern => format!(
867+
"{output_file_path}.pdb",
868+
output_file_path = fpath.file_name().unwrap().to_string_lossy()
869+
),
870+
},
871+
native_companion_file = if *NATIVE_PASSTROUGH {
872+
format!(
873+
"rust_native_{output_file_path}.so",
874+
output_file_path = file_stem(output_file_path)
875+
)
876+
} else {
877+
String::new()
878+
}
879+
)
880+
}
835881
lazy_static! {
836882
#[doc = "Tells the codegen compile linked static libraries into a shared library, which will be bundled with the .NET executable."]pub static ref NATIVE_PASSTROUGH:bool = {
837883
std::env::vars().find_map(|(key,value)|if key == stringify!(NATIVE_PASSTROUGH){
@@ -865,6 +911,17 @@ lazy_static! {
865911
}).unwrap_or(false)
866912
};
867913
}
914+
lazy_static! {
915+
#[doc = "Tells the codegen to emmit JS source files."]pub static ref JS_MODE:bool = {
916+
std::env::vars().find_map(|(key,value)|if key == stringify!(JS_MODE){
917+
Some(value)
918+
}else {
919+
None
920+
}).map(|value|match value.as_ref(){
921+
"0"|"false"|"False"|"FALSE" => false,"1"|"true"|"True"|"TRUE" => true,_ => panic!("Boolean enviroment variable {} has invalid value {}",stringify!(C_MODE),value),
922+
}).unwrap_or(false)
923+
};
924+
}
868925
fn override_errno(asm: &mut Assembly) {
869926
for method in asm.methods_mut() {
870927
if method.name().contains("errno")

cilly/src/c_exporter/mod.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
use crate::asm::AssemblyExternRef;
22
use crate::asm_exporter::{AssemblyExportError, AssemblyExporter, AssemblyInfo};
3-
use crate::cil_node::CILNode;
4-
use crate::cil_root::CILRoot;
5-
use crate::cil_tree::CILTree;
63
use crate::method::Method;
74
use crate::type_def::TypeDef;
85

96
mod method;
10-
use crate::DepthSetting;
7+
use crate::{escape_type_name, DepthSetting};
118
use crate::{r#type::Type, IString};
129
use std::collections::HashMap;
13-
use std::hash::Hasher;
1410
use std::process::Command;
1511
use std::{borrow::Cow, collections::HashSet, io::Write};
1612
mod varaible;
@@ -80,16 +76,6 @@ impl CExporter {
8076
}
8177
}
8278

83-
fn escape_type_name(name: &str) -> String {
84-
name.replace(['.', ' '], "_")
85-
.replace('<', "lt")
86-
.replace('>', "gt")
87-
.replace('$', "ds")
88-
.replace(',', "cm")
89-
.replace('{', "bs")
90-
.replace('}', "be")
91-
.replace('+', "ps")
92-
}
9379
impl CExporter {
9480
fn as_source(&self, is_dll: bool) -> Vec<u8> {
9581
let mut res = self.headers.clone();

cilly/src/cil_node.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,8 @@ impl CILNode {
11011101
));
11021102
}
11031103
}
1104+
(Type::DelegatePtr(_),Type::ISize)=>(),
1105+
(Type::DotnetType(ty_a), Type::DotnetType(ty_b)) if !ty_a.is_valuetype() && !ty_b.is_valuetype() =>(),
11041106
_ => {
11051107
return Err(format!(
11061108
"Expected an argument of type {tpe:?}, but got {arg:?} when calling the ctor of {class:?}", class = call_op_args.site.class()
@@ -1220,6 +1222,13 @@ impl CILNode {
12201222
_ => panic!("{arr:?} is not an array!"),
12211223
}
12221224
}
1225+
Self::LDLen { arr } => {
1226+
let arr = arr.validate(vctx, tmp_loc)?;
1227+
match arr {
1228+
Type::ManagedArray { element, dims } => Ok(Type::I32),
1229+
_ => panic!("{arr:?} is not an array!"),
1230+
}
1231+
}
12231232
Self::LocAlloc { size } => {
12241233
size.validate(vctx, tmp_loc)?;
12251234
Ok(ptr!(Type::Void))

cilly/src/js_exporter/defines.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
var globalMemoryArray = new ArrayBuffer(4096 + 4096 * 8 + 4096 * 64);
2+
var globalMemory = new DataView(globalMemoryArray);
3+
var stackPointer = 4096n;
4+
var heapPointer = 4096n + 4096n * 8n;
5+
function System_Runtime_InteropServices_NativeMemory_AlignedAlloc_usus(size, align) {
6+
// Round up
7+
if (heapPointer % align != 0) {
8+
const freeBlockSize = heapPointer % align;
9+
const freeBlockStart = heapPointer;
10+
heapPointer += freeBlockSize;
11+
}
12+
const newBuffer = heapPointer;
13+
heapPointer += size;
14+
console.log(`allocating a buffer of size ${size} align ${align} at address ${newBuffer}`);
15+
return newBuffer;
16+
}
17+
function System_Environment_GetCommandLineArgs_() {
18+
if (process) {
19+
return process.argv;
20+
} else {
21+
return [""];
22+
}
23+
}
24+
function i32_to_u32(i32) {
25+
return (i32 & 2147483647) | Math.sign(i32) << 32;
26+
}

0 commit comments

Comments
 (0)