mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
give the new exposed symbols to the surgical linker
This commit is contained in:
parent
fee5e978f7
commit
454f3c603e
11 changed files with 163 additions and 75 deletions
|
@ -7,7 +7,8 @@ use memmap2::{Mmap, MmapMut};
|
|||
use object::Object;
|
||||
use roc_build::link::{get_target_triple_str, rebuild_host, LinkType};
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_load::{EntryPoint, ExecutionMode, LoadConfig, Threading};
|
||||
use roc_load::{EntryPoint, ExecutionMode, ExposedToHost, LoadConfig, Threading};
|
||||
use roc_module::symbol::Interns;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_reporting::report::{RenderTarget, DEFAULT_PALETTE};
|
||||
|
@ -59,8 +60,25 @@ pub fn build_and_preprocess_host(
|
|||
target: &Triple,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
exposed_to_host: Vec<String>,
|
||||
exported_closure_types: Vec<String>,
|
||||
exposed_symbols: ExposedSymbols,
|
||||
) {
|
||||
let stub_dll_symbols = exposed_symbols.stub_dll_symbols();
|
||||
|
||||
build_and_preprocess_host_lowlevel(
|
||||
opt_level,
|
||||
target,
|
||||
platform_main_roc,
|
||||
preprocessed_host_path,
|
||||
&stub_dll_symbols,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn build_and_preprocess_host_lowlevel(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
) {
|
||||
let stub_lib = if let target_lexicon::OperatingSystem::Windows = target.operating_system {
|
||||
platform_main_roc.with_file_name("libapp.dll")
|
||||
|
@ -74,7 +92,6 @@ pub fn build_and_preprocess_host(
|
|||
platform_main_roc.with_file_name("dynhost")
|
||||
};
|
||||
|
||||
let stub_dll_symbols = make_stub_dll_symbols(exposed_to_host, exported_closure_types);
|
||||
generate_dynamic_lib(target, &stub_dll_symbols, &stub_lib);
|
||||
rebuild_host(opt_level, target, platform_main_roc, Some(&stub_lib));
|
||||
|
||||
|
@ -137,7 +154,7 @@ pub fn generate_stub_lib(
|
|||
|
||||
let exposed_to_host = loaded
|
||||
.exposed_to_host
|
||||
.values
|
||||
.top_level_values
|
||||
.keys()
|
||||
.map(|x| x.as_str(&loaded.interns).to_string())
|
||||
.collect();
|
||||
|
@ -155,6 +172,11 @@ pub fn generate_stub_lib(
|
|||
})
|
||||
.collect();
|
||||
|
||||
let exposed_symbols = ExposedSymbols {
|
||||
top_level_values: exposed_to_host,
|
||||
exported_closure_types,
|
||||
};
|
||||
|
||||
if let EntryPoint::Executable { platform_path, .. } = &loaded.entry_point {
|
||||
let stub_lib = if let target_lexicon::OperatingSystem::Windows = triple.operating_system {
|
||||
platform_path.with_file_name("libapp.obj")
|
||||
|
@ -162,7 +184,7 @@ pub fn generate_stub_lib(
|
|||
platform_path.with_file_name("libapp.so")
|
||||
};
|
||||
|
||||
let stub_dll_symbols = make_stub_dll_symbols(exposed_to_host, exported_closure_types);
|
||||
let stub_dll_symbols = exposed_symbols.stub_dll_symbols();
|
||||
generate_dynamic_lib(triple, &stub_dll_symbols, &stub_lib);
|
||||
} else {
|
||||
unreachable!();
|
||||
|
@ -170,33 +192,88 @@ pub fn generate_stub_lib(
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
fn make_stub_dll_symbols(
|
||||
exposed_to_host: Vec<String>,
|
||||
exported_closure_types: Vec<String>,
|
||||
) -> Vec<String> {
|
||||
let mut custom_names = Vec::new();
|
||||
pub struct ExposedSymbols {
|
||||
// usually just `mainForhost`
|
||||
pub top_level_values: Vec<String>,
|
||||
|
||||
for sym in exposed_to_host {
|
||||
custom_names.extend([
|
||||
format!("roc__{}_1_exposed", sym),
|
||||
format!("roc__{}_1_exposed_generic", sym),
|
||||
format!("roc__{}_size", sym),
|
||||
]);
|
||||
// old type exposing mechanism
|
||||
pub exported_closure_types: Vec<String>,
|
||||
}
|
||||
|
||||
impl ExposedSymbols {
|
||||
pub fn from_exposed_to_host(interns: &Interns, exposed_to_host: &ExposedToHost) -> Vec<String> {
|
||||
let mut custom_names = Vec::new();
|
||||
|
||||
for x in exposed_to_host.top_level_values.keys() {
|
||||
let sym = x.as_str(interns);
|
||||
|
||||
for closure_type in &exported_closure_types {
|
||||
custom_names.extend([
|
||||
format!("roc__{}_1_{}_caller", sym, closure_type),
|
||||
format!("roc__{}_1_{}_size", sym, closure_type),
|
||||
format!("roc__{}_1_{}_result_size", sym, closure_type),
|
||||
format!("roc__{}_1_exposed", sym),
|
||||
format!("roc__{}_1_exposed_generic", sym),
|
||||
format!("roc__{}_size", sym),
|
||||
]);
|
||||
|
||||
let exported_closure_types = exposed_to_host
|
||||
.closure_types
|
||||
.iter()
|
||||
.map(|x| format!("{}_{}", x.module_string(interns), x.as_str(interns)));
|
||||
|
||||
for closure_type in exported_closure_types {
|
||||
custom_names.extend([
|
||||
format!("roc__{}_1_{}_caller", sym, closure_type),
|
||||
format!("roc__{}_1_{}_size", sym, closure_type),
|
||||
format!("roc__{}_1_{}_result_size", sym, closure_type),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
for x in &exposed_to_host.getters {
|
||||
let sym = x.as_str(interns);
|
||||
custom_names.extend([
|
||||
format!("{sym}"),
|
||||
format!("{sym}_generic"),
|
||||
format!("roc__{sym}_size"),
|
||||
]);
|
||||
}
|
||||
|
||||
for (top_level_value, lambda_set_id) in &exposed_to_host.lambda_sets {
|
||||
let sym = top_level_value.as_str(interns);
|
||||
let id = lambda_set_id.0;
|
||||
custom_names.extend([format!("roc__{sym}_{id}_caller")]);
|
||||
}
|
||||
|
||||
// on windows (PE) binary search is used on the symbols,
|
||||
// so they must be in alphabetical order
|
||||
custom_names.sort_unstable();
|
||||
|
||||
custom_names
|
||||
}
|
||||
|
||||
// on windows (PE) binary search is used on the symbols,
|
||||
// so they must be in alphabetical order
|
||||
custom_names.sort_unstable();
|
||||
fn stub_dll_symbols(&self) -> Vec<String> {
|
||||
let mut custom_names = Vec::new();
|
||||
|
||||
custom_names
|
||||
for sym in &self.top_level_values {
|
||||
custom_names.extend([
|
||||
format!("roc__{}_1_exposed", sym),
|
||||
format!("roc__{}_1_exposed_generic", sym),
|
||||
format!("roc__{}_size", sym),
|
||||
]);
|
||||
|
||||
for closure_type in &self.exported_closure_types {
|
||||
custom_names.extend([
|
||||
format!("roc__{}_1_{}_caller", sym, closure_type),
|
||||
format!("roc__{}_1_{}_size", sym, closure_type),
|
||||
format!("roc__{}_1_{}_result_size", sym, closure_type),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// on windows (PE) binary search is used on the symbols,
|
||||
// so they must be in alphabetical order
|
||||
custom_names.sort_unstable();
|
||||
|
||||
custom_names
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_dynamic_lib(target: &Triple, stub_dll_symbols: &[String], stub_lib_path: &Path) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue