Skip to content

Commit 726aca4

Browse files
committed
Support both user-defined and standard library structs and tuples. Tests added to ensure this works.
1 parent 324671f commit 726aca4

File tree

18 files changed

+1835
-616
lines changed

18 files changed

+1835
-616
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ regex = "1.11.1"
88
ristretto_classfile = { version = "0.16.0" }
99
serde = { version = "1.0.219", features = ["derive"] }
1010
serde_json = "1.0.140"
11+
sha2 = "0.10.8"
1112

1213
[lib]
1314
crate-type = ["dylib"]

Readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ This backend currently supports a subset of Rust features:
3939
* ✅ Basic variable assignment (`let x = y;`).
4040
* ✅ Arrays and slices.
4141
* ✅ Floats (`f32`, `f64`).
42+
* ✅ Structs and Tuples (enums and unions coming soon!)
4243
* ✅ Generating executable `.jar` files for binary crates.
4344

4445
### Next Milestone:

java-linker/src/main.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ fn create_jar(
357357
zip_writer.start_file("META-INF/MANIFEST.MF", options)?;
358358
zip_writer.write_all(manifest_content.as_bytes())?;
359359

360-
let re = Regex::new(r"^(.*?)-[0-9a-fA-F]+(\.class)$").unwrap();
360+
let re = Regex::new(r"^[^-]+-[0-9a-fA-F]+\.(?P<name>[^/\\]+\.class)$").unwrap();
361361
let mut added_class_files = std::collections::HashSet::new();
362362

363363
for input_file_path_str in input_files {
@@ -439,16 +439,11 @@ fn create_jar(
439439
})?;
440440

441441
let jar_entry_name = if let Some(caps) = re.captures(original_file_name) {
442-
format!("{}{}", &caps[1], &caps[2])
442+
caps["name"].to_string()
443443
} else {
444-
// If not hashed, assume the filename corresponds to the path within the JAR.
445-
// This might need adjustment depending on how class files are laid out relative
446-
// to their package structure on the filesystem before being passed to the linker.
447-
// For now, we just use the filename. A better approach might involve stripping
448-
// a known source root path.
449444
original_file_name.to_string()
450445
};
451-
446+
452447
if !added_class_files.contains(&jar_entry_name) {
453448
let is_known_good = known_good_identifier
454449
.map(|id| input_file_path_str.contains(id))

library/src/main/kotlin/org/rustlang/core/Core.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,16 @@ public object Core {
5656
}
5757
return sb.toString()
5858
}
59+
60+
@JvmStatic
61+
public fun to_string(value: Any?): String {
62+
// Convert the value to a string.
63+
return value?.toString() ?: "null"
64+
}
65+
66+
@JvmStatic
67+
public fun eq(value1: Any?, value2: Any?): Boolean {
68+
// Check for equality.
69+
return value1 == value2
70+
}
5971
}

shim-metadata-gen/core.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@
2323
"descriptor": "(I)Ljava/lang/String;",
2424
"is_static": true
2525
},
26+
"eq": {
27+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
28+
"is_static": true
29+
},
2630
"panic_fmt": {
2731
"descriptor": "(Ljava/lang/String;)V",
2832
"is_static": true
33+
},
34+
"to_string": {
35+
"descriptor": "(Ljava/lang/Object;)Ljava/lang/String;",
36+
"is_static": true
2937
}
3038
}

src/lib.rs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use rustc_metadata::EncodedMetadata;
3030
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
3131
use rustc_middle::ty::TyCtxt;
3232
use rustc_session::{Session, config::OutputFilenames};
33-
use std::{any::Any, io::Write, path::Path, vec};
33+
use std::{any::Any, io::Write, path::Path};
3434

3535
mod lower1;
3636
mod lower2;
@@ -57,6 +57,7 @@ impl CodegenBackend for MyBackend {
5757
let mut oomir_module = oomir::Module {
5858
name: crate_name.clone(),
5959
functions: std::collections::HashMap::new(),
60+
data_types: std::collections::HashMap::new(),
6061
};
6162

6263
// Iterate through all items in the crate and find functions
@@ -82,12 +83,16 @@ impl CodegenBackend for MyBackend {
8283
println!("MIR for function {i}: {:?}", mir);
8384

8485
println!("--- Starting MIR to OOMIR Lowering for function: {i} ---");
85-
let oomir_function = lower1::mir_to_oomir(tcx, instance, &mut mir);
86+
let oomir_result = lower1::mir_to_oomir(tcx, instance, &mut mir);
8687
println!("--- Finished MIR to OOMIR Lowering for function: {i} ---");
8788

89+
let oomir_function = oomir_result.0;
90+
8891
oomir_module
8992
.functions
9093
.insert(oomir_function.name.clone(), oomir_function);
94+
95+
oomir_module.merge_data_types(&oomir_result.1);
9196
}
9297
}
9398

@@ -119,30 +124,46 @@ impl CodegenBackend for MyBackend {
119124
outputs: &OutputFilenames,
120125
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
121126
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
122-
let (bytecode, crate_name, metadata, crate_info) = *ongoing_codegen
123-
.downcast::<(Vec<u8>, String, EncodedMetadata, CrateInfo)>()
124-
.expect("in join_codegen: ongoing_codegen is not bytecode vector");
125-
126-
let class_path = outputs.temp_path_ext("class", None);
127-
128-
let mut class_file =
129-
std::fs::File::create(&class_path).expect("Could not create the Java .class file!");
130-
class_file
131-
.write_all(&bytecode)
132-
.expect("Could not write Java bytecode to file!");
133-
134-
let modules = vec![CompiledModule {
135-
name: crate_name,
136-
kind: ModuleKind::Regular,
137-
object: Some(class_path),
138-
bytecode: None,
139-
dwarf_object: None,
140-
llvm_ir: None,
141-
links_from_incr_cache: Vec::new(),
142-
assembly: None,
143-
}];
127+
// Update the downcast to expect a HashMap now.
128+
let (bytecode_map, _, metadata, crate_info) = *ongoing_codegen
129+
.downcast::<(
130+
std::collections::HashMap<String, Vec<u8>>,
131+
String,
132+
EncodedMetadata,
133+
CrateInfo,
134+
)>()
135+
.expect("in join_codegen: ongoing_codegen is not a bytecode map");
136+
137+
let mut compiled_modules = Vec::new();
138+
139+
// Iterate over each (file_name, bytecode) pair in the map.
140+
for (name, bytecode) in bytecode_map.into_iter() {
141+
// The key is expected to be the file name without the ".class" extension.
142+
// Append ".class" here.
143+
let file_name = format!("{}.class", name);
144+
let file_path = outputs.temp_path_ext(&file_name, None);
145+
146+
// Write the bytecode to the file
147+
let mut file = std::fs::File::create(&file_path)
148+
.unwrap_or_else(|e| panic!("Could not create file {}: {}", file_path.display(), e));
149+
file.write_all(&bytecode)
150+
.unwrap_or_else(|e| panic!("Could not write bytecode to file {}: {}", file_path.display(), e));
151+
152+
// Create a CompiledModule for this file
153+
compiled_modules.push(CompiledModule {
154+
name: name.clone(),
155+
kind: ModuleKind::Regular,
156+
object: Some(file_path),
157+
bytecode: None,
158+
dwarf_object: None,
159+
llvm_ir: None,
160+
links_from_incr_cache: Vec::new(),
161+
assembly: None,
162+
});
163+
}
164+
144165
let codegen_results = CodegenResults {
145-
modules,
166+
modules: compiled_modules,
146167
allocator_module: None,
147168
metadata_module: None,
148169
metadata,
@@ -152,7 +173,7 @@ impl CodegenBackend for MyBackend {
152173
}))
153174
.expect("Could not join_codegen")
154175
}
155-
176+
156177
fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) {
157178
println!("linking!");
158179
use rustc_codegen_ssa::back::link::link_binary;

0 commit comments

Comments
 (0)