v.gen.fastc #
The self-host C is emitted without a single #include: everything it takes from the C library is declared here, per target, from a table kept in V. The prelude replaces the header block of the preamble, so the declarations below are exactly what TinyCC otherwise parsed out of the system headers (about 60K preprocessed lines per build), and every C function the emitted code may call gets a prototype with its real C types, which keeps argument conversions identical to a header-based build. -Werror=implicit-function- declaration is passed along, so a call to a C function missing from the table fails the build instead of being compiled with an implicit int signature. c_abi_test.v checks the table against the host headers.
fn fastc_add_prepared_link_input #
fn fastc_add_prepared_link_input(mut link FastcPreparedLink, input_path string) !
fastc_add_prepared_link_input loads one completed object into the macOS in-process linker. Callers preserve the original object order.
fn fastc_begin_feed_prestarted_c_units #
fn fastc_begin_feed_prestarted_c_units(mut prestarted FastcPrestartedCUnits, mut rendering FastcRenderingCUnits) !FastcFeedingCUnits
fastc_begin_feed_prestarted_c_units starts copying rendered source to TinyCC processes that were launched while FastC generation was still running.
fn fastc_begin_native_compile #
fn fastc_begin_native_compile(program string, base_args []string, source string, object string) FastcNativeCompile
fastc_begin_native_compile compiles one native source while the program's translation units are being compiled. The caller owns the output directory until fastc_finish_native_compile or fastc_discard_native_compile returns.
fn fastc_begin_render_c_units #
fn fastc_begin_render_c_units(prefix string, pieces []string, units FastcUnitLayout, jobs int) FastcRenderingCUnits
fastc_begin_render_c_units starts rendering balanced split translation units and returns immediately, so their consumers can start concurrently.
fn fastc_begin_render_prestarted_c_units #
fn fastc_begin_render_prestarted_c_units(mut prestarted FastcPrestartedCUnits, prefix string, pieces []string, units FastcUnitLayout, jobs int) !FastcFeedingCUnits
fastc_begin_render_prestarted_c_units renders directly into prestarted TinyCC processes, avoiding a second set of threads just to hand strings off.
fn fastc_codesign_shim_dir #
fn fastc_codesign_shim_dir() FastcCodesignShim
fastc_codesign_shim_dir prepares the shared Mach-O signer's temporary codesign shim.
fn fastc_compile_c_unit_texts #
fn fastc_compile_c_unit_texts(tcc string, base_args []string, unit_paths []string, sources []string, prepared FastcPreparedUnits) ![]string
fastc_compile_c_unit_texts streams in-memory translation units to concurrent TinyCC processes. This avoids a temporary-file write/read round trip and overlaps feeding earlier processes with starting the remaining ones.
fn fastc_compile_c_units #
fn fastc_compile_c_units(tcc string, base_args []string, unit_paths []string, prepared FastcPreparedUnits) ![]string
fastc_compile_c_units compiles the translation units to objects with concurrent TinyCC processes (started with posix_spawn, which is cheaper than forking the compiler process), and returns the object paths, or the output of the first compile that failed.
fn fastc_compile_prestarted_rendering_c_units #
fn fastc_compile_prestarted_rendering_c_units(mut prestarted FastcPrestartedCUnits, mut rendering FastcRenderingCUnits, prepared FastcPreparedUnits, mut prepared_link FastcPreparedLink, preload_link bool) ![]string
fastc_compile_prestarted_rendering_c_units feeds and waits for translation units in one call. Callers with independent setup work can use the split begin/finish API to overlap that work with rendering and compilation.
fn fastc_compile_rendering_c_units #
fn fastc_compile_rendering_c_units(tcc string, base_args []string, mut rendering FastcRenderingCUnits, prepared FastcPreparedUnits, mut prepared_link FastcPreparedLink, preload_link bool) ![]string
fastc_compile_rendering_c_units starts concurrent TinyCC processes while their translation units are still being rendered, then streams each unit as soon as its render worker completes.
fn fastc_compile_zygote_c_units #
fn fastc_compile_zygote_c_units(mut zygote FastcZygote, base_args []string, objects []string, pieces []string, units FastcUnitLayout, plan FastcZygotePlan, mut prepared_link FastcPreparedLink, preload_link bool) !
fastc_compile_zygote_c_units compiles the planned units to objects with the zygote, which is used up by this. With preload_link every object is loaded into the prepared linker, in unit order, as soon as it and those before it exist.
fn fastc_discard_link #
fn fastc_discard_link(mut link FastcPreparedLink)
fastc_discard_link releases a prepared linker after unit compilation fails.
fn fastc_discard_native_compile #
fn fastc_discard_native_compile(mut compile FastcNativeCompile)
fastc_discard_native_compile waits before its temporary directory is removed.
fn fastc_discard_prestarted_c_units #
fn fastc_discard_prestarted_c_units(mut units FastcPrestartedCUnits)
fastc_discard_prestarted_c_units closes and reaps unused prestarted TinyCC processes, then removes their private build directory.
fn fastc_discard_zygote #
fn fastc_discard_zygote(mut zygote FastcZygote)
fastc_discard_zygote ends a zygote that received no job and reaps it.
fn fastc_finish_link #
fn fastc_finish_link(mut link FastcPreparedLink, input_paths []string, final_args []string, output string) os.Result
fastc_finish_link adds the compiled inputs to a prepared linker and writes the executable. final_args contains libraries and other link-only flags.
fn fastc_finish_native_compile #
fn fastc_finish_native_compile(mut compile FastcNativeCompile) ?string
fastc_finish_native_compile returns a clean object, or none so the caller can keep its original source operand and diagnostics. It waits at most once.
fn fastc_finish_prestarted_c_units #
fn fastc_finish_prestarted_c_units(mut prestarted FastcPrestartedCUnits, mut feeding FastcFeedingCUnits, prepared FastcPreparedUnits, mut prepared_link FastcPreparedLink, preload_link bool) ![]string
fastc_finish_prestarted_c_units waits for TinyCC and optionally loads each completed object into the prepared linker in translation-unit order.
fn fastc_finish_render_c_units #
fn fastc_finish_render_c_units(mut rendering FastcRenderingCUnits) FastcRenderedCUnits
fastc_finish_render_c_units waits for an in-progress unit render.
fn fastc_flag_is_native_input #
fn fastc_flag_is_native_input(flag string) bool
fastc_flag_is_native_input reports whether a flag is a native source or link input.
fn fastc_generation_link_cache_key #
fn fastc_generation_link_cache_key(tcc string, compile_args []string, final_args []string, pieces []string, units FastcUnitLayout, jobs int, enabled bool) string
fastc_generation_link_cache_key identifies the final executable directly from the generated pieces and every input that affects unit compilation or linking. A warm build can therefore restore the executable before writing and re-reading the split C files.
fn fastc_link_cache_key #
fn fastc_link_cache_key(unit_key string, final_args []string) string
fastc_link_cache_key identifies a link of content-addressed unit objects.
fn fastc_macos_system_tbd #
fn fastc_macos_system_tbd(target_arch string) string
fastc_macos_system_tbd returns a compact libSystem text stub containing the complete macOS ABI table used by header-free FastC self-host builds. Passing this to TinyCC avoids parsing the SDK's much larger umbrella stub at link time while retaining the same libSystem install name.
fn fastc_native_args_adapter #
fn fastc_native_args_adapter(name string, prototype string) ?FastcNativeArgsAdapter
fastc_native_args_adapter returns the adapter that the native bridge function name, declared by prototype (see fastc_native_function_declaration), needs on arm64 macOS. A call whose arguments fit in registers, or that passes a function or a variable argument list, keeps its direct call. A struct counts as two integer and four floating-point registers, the most it can take; an unneeded adapter only adds a call.
fn fastc_payload_object #
fn fastc_payload_object(tcc string, base_args []string, pieces []string, build_dir string, use_cache bool) FastcPayloadObject
fastc_payload_object returns the object of a payload unit, from the unit cache when use_cache is set and the same TinyCC and arguments already compiled that text. Without a payload there is no object. The text is joined only to compile it.
fn fastc_prepare_c_units #
fn fastc_prepare_c_units(tcc string, base_args []string, unit_paths []string, cache_enabled bool) FastcPreparedUnits
fastc_prepare_c_units calculates the object cache keys and restores hits.
fn fastc_prepare_link #
fn fastc_prepare_link(program string, tcc_lib string, base_args []string, final_args []string) FastcPreparedLink
fastc_prepare_link initializes the in-process TinyCC linker on macOS. A compiler built by TinyCC or the V3 backend uses the executable-based linker instead. final_args are supplied here so state-affecting linker options are visible before TinyCC initializes its output state.
fn fastc_prepared_link_accepts_inputs #
fn fastc_prepared_link_accepts_inputs(link &FastcPreparedLink) bool
fastc_prepared_link_accepts_inputs reports whether object files can be loaded into this linker before the final output step.
fn fastc_prepared_link_skips_codesign #
fn fastc_prepared_link_skips_codesign(link &FastcPreparedLink) bool
fastc_prepared_link_skips_codesign reports whether the prepared linker suppresses TinyCC's codesign subprocess and needs in-process signing.
fn fastc_prestart_c_units #
fn fastc_prestart_c_units(tcc string, base_args []string, build_dir string, unit_count int) FastcPrestartedCUnits
fastc_prestart_c_units starts TinyCC processes that wait for their source on stdin. Starting this on a worker lets source generation hide process launch.
fn fastc_prestarted_c_units_match #
fn fastc_prestarted_c_units_match(units &FastcPrestartedCUnits, base_args []string, unit_count int) bool
fastc_prestarted_c_units_match reports whether units can consume a build with the final compile arguments and translation-unit count.
fn fastc_publish_link_cache #
fn fastc_publish_link_cache(key string, output string)
fastc_publish_link_cache atomically caches a linked and signed self-host.
fn fastc_remove_c_units #
fn fastc_remove_c_units(unit_paths []string)
FastcUnitCompile is one TinyCC process compiling a translation unit. fastc_remove_c_units deletes the translation unit sources and their objects.
fn fastc_remove_codesign_shim_dir #
fn fastc_remove_codesign_shim_dir(shim FastcCodesignShim)
fastc_remove_codesign_shim_dir restores PATH and removes the temporary codesign shim.
fn fastc_render_c_units #
fn fastc_render_c_units(prefix string, pieces []string, units FastcUnitLayout, jobs int) FastcRenderedCUnits
fastc_render_c_units renders balanced split translation units in parallel.
fn fastc_restore_link_cache #
fn fastc_restore_link_cache(key string, output string) bool
fastc_restore_link_cache copies a cached linked self-host to output.
fn fastc_run_command #
fn fastc_run_command(program string, args []string) os.Result
fastc_run_command runs the program with the argument vector and returns its exit code and merged output, like cmdexec.run, but through posix_spawn and a blocking wait rather than a fork of this (large) process and a polling loop.
fn fastc_sign_macho_adhoc #
fn fastc_sign_macho_adhoc(path string) !
fastc_sign_macho_adhoc gives the executable at path an ad-hoc Mach-O signature.
fn fastc_split_payload_unit #
fn fastc_split_payload_unit(pieces []string, units FastcUnitLayout, jobs int) FastcPayloadUnit
fastc_split_payload_unit moves the embedded files out of the first unit of a split build. Their escaped bytes made that unit the slowest TinyCC job of a large program.
fn fastc_start_zygote #
fn fastc_start_zygote(max_units int, head_path string) FastcZygote
fastc_start_zygote forks the zygotes of a build, which keeps its head in head_path when that is not empty. A compiler without an in-process TinyCC returns an inactive zygote, as does a failed fork or V3_FASTC_NO_ZYGOTE.
fn fastc_tcc_job_count #
fn fastc_tcc_job_count(prefs &pref.Preferences) int
fastc_tcc_job_count is the number of TinyCC processes a driver compiles a program's translation units with.
fn fastc_write_c_units #
fn fastc_write_c_units(prefix string, pieces []string, units FastcUnitLayout, jobs int) ![]string
fastc_write_c_units writes the translation units of a generation for jobs parallel TinyCC processes: prefix.unit<k>.c files, each with the shared head (the globals as extern declarations after the first), the first also with the startup, cleanup and main pieces, and consecutive body units grouped to balance their sizes. It returns the paths, or none when the program does not split.
fn fastc_zygote_accepts #
fn fastc_zygote_accepts(zygote &FastcZygote, compile_args []string) bool
fastc_zygote_accepts reports whether the zygote can compile units with compile_args. Its units part at a #warning, which these options would suppress or turn into an error.
fn fastc_zygote_head_path #
fn fastc_zygote_head_path(input string) string
fastc_zygote_head_path names the file in which the builds of input by this compiler keep their head for the next build.
fn fastc_zygote_plan #
fn fastc_zygote_plan(prefix string, pieces []string, units FastcUnitLayout, max_units int) FastcZygotePlan
fastc_zygote_plan balances the definitions and the body units of a generation over at most max_units zygote units. It returns no paths when the program does not split.
fn fastc_zygote_unit_limit #
fn fastc_zygote_unit_limit(prefs &pref.Preferences) int
fastc_zygote_unit_limit is the largest number of units a zygote compiles at once. A unit costs a zygote one more process, not one more parse of the head.
fn generate #
fn generate(source string, path string, prefs &pref.Preferences) !string
generate scans V source and emits C as each declaration and statement is consumed. It does not construct an AST or invoke semantic type checking. Unsupported syntax is returned as an error; FastC never retries through an AST-based backend.
fn generate_files #
fn generate_files(paths []string, prefs &pref.Preferences) !string
generate_files discovers imports from the input files or directories and emits one C unit for the complete source graph. Discovery and generation use scanner tokens only.
fn generate_files_with_native_aliases #
fn generate_files_with_native_aliases(paths []string, prefs &pref.Preferences, native_aliases []string) !GenerationResult
generate_files_with_native_aliases redirects qualified C function references to native owners.
fn generate_files_with_source_paths #
fn generate_files_with_source_paths(paths []string, prefs &pref.Preferences) !GenerationResult
generate_files_with_source_paths emits C and reports every source read from entry files, entry directories, and their imports.
fn write_c_pieces #
fn write_c_pieces(path string, pieces []string) !
write_c_pieces writes generated C pieces to path without joining them. Large outputs use a bounded buffer; write, final flush, and close errors propagate.
type FastcCodesignShim #
type FastcCodesignShim = machosign.CodesignShim
FastcCodesignShim owns the temporary codesign shim and its previous PATH value.
struct FastcFeedingCUnits #
struct FastcFeedingCUnits {
pub:
paths []string
mut:
writers []thread bool
}
FastcFeedingCUnits holds the workers that copy rendered translation units into prestarted TinyCC processes.
struct FastcNativeArgsAdapter #
struct FastcNativeArgsAdapter {
pub:
name string
return_type string
// parameter_types are plain C types; a pointer of any kind is `void*`.
parameter_types []string
}
FastcNativeArgsAdapter describes a native bridge function whose arguments do not all fit in registers. TinyCC does not lay out arm64 stack arguments as Apple's ABI packs them, so the TinyCC program passes such a call's arguments in one struct, and a platform-compiled adapter makes the call.
fn (FastcNativeArgsAdapter) native_side #
fn (adapter FastcNativeArgsAdapter) native_side() string
native_side defines the adapter in the platform-compiled bridge. It calls the native function through a pointer of the declared argument types, which have the sizes of the native ones, so no conversion of an Objective-C argument is involved.
fn (FastcNativeArgsAdapter) program_side #
fn (adapter FastcNativeArgsAdapter) program_side() string
program_side routes the TinyCC program's calls of the bridge pointer through the adapter. A use of the pointer that is not a call keeps the direct pointer.
struct FastcNativeCompile #
struct FastcNativeCompile {
mut:
worker thread os.Result
object string
active bool
}
FastcNativeCompile holds an independent native compilation in this build.
struct FastcPayloadObject #
struct FastcPayloadObject {
pub:
path string
error string
}
FastcPayloadObject is the compiled payload unit: an object path, or the TinyCC error.
struct FastcPayloadUnit #
struct FastcPayloadUnit {
pub:
// units declares the payloads `extern` in the first unit too.
units FastcUnitLayout
// pieces define every payload; there are none when the build keeps them in place.
// They stay apart: the payloads of a large program are tens of megabytes.
pieces []string
}
FastcPayloadUnit is the embedded-file data of a split build, compiled apart from the generated code. It names no header, so its object depends only on its own text.
fn (FastcPayloadUnit) source #
fn (unit &FastcPayloadUnit) source() string
source returns the text of the payload unit.
struct FastcPreparedLink #
struct FastcPreparedLink {
mut:
state voidptr
diagnostics voidptr
program string
base_args []string
}
FastcPreparedLink holds a linker that can be initialized concurrently with the TinyCC processes compiling a program's translation units.
struct FastcPreparedUnits #
struct FastcPreparedUnits {
entries []FastcUnitCacheEntry
pub:
objects []string
cache_key string
}
FastcPreparedUnits holds the ordered TinyCC objects and their content cache entries. Preparing them restores object-cache hits before compilation starts.
fn (FastcPreparedUnits) cache_objects #
fn (prepared &FastcPreparedUnits) cache_objects() map[string]string
cache_objects maps build-local objects to their persistent cache entries for reporting linker failures, including units published during this build.
struct FastcPrestartedCUnits #
struct FastcPrestartedCUnits {
pub:
build_dir string
base_args []string
unit_count int
mut:
paths []string
objects []string
pids []int
read_fds []int
write_fds []int
active bool
pub mut:
// zygote compiles the units of a build that does not use the processes above.
zygote FastcZygote
}
FastcPrestartedCUnits holds TinyCC processes started before FastC generation completes. They wait on stdin until the balanced translation units are ready.
struct FastcRenderedCUnits #
struct FastcRenderedCUnits {
pub:
paths []string
sources []string
}
FastcRenderedCUnits holds split translation units in memory so an uncached build can stream them to TinyCC without temporary C files.
struct FastcRenderingCUnits #
struct FastcRenderingCUnits {
pub:
paths []string
mut:
workers []thread string
order []int
}
FastcRenderingCUnits holds translation-unit render workers. Keeping the workers live lets an uncached build start TinyCC while the C text is still being assembled.
struct FastcUnitLayout #
struct FastcUnitLayout {
pub mut:
head_end int
solo_end int
unit_starts []int
extern_indexes []int
extern_texts []string
// native_headers have consumers fully described by V's function bindings.
// Keep their implementations in the native owner, without opening the headers.
native_headers []string
prototype_start int
prototype_end int
prototype_texts []string
unit_ref_starts []int
unit_ref_ids []int
solo_prototype_ids []int
shared_prototype_ids []int
tail_prototype_ids []int
// tail_unit is the first unit that needs tail_prototype_ids: the last source
// file's bodies, followed by units of on-demand generic instances.
tail_unit int
// define_texts are the same pieces with `static` dropped, for the first
// unit: a static definition would not satisfy the other units' externs.
define_texts []string
// solo_starts index the pieces between head_end and solo_end at which a
// group of complete definitions begins. Every unit declares them, so a
// build that shares one parse of the head may spread them over its units.
solo_starts []int
}
FastcUnitLayout locates, in a generation's pieces, the shared head (types, constants, globals, prototypes, runtime), the pieces that belong to one unit only (the startup initializer, the cleanup hook and the synthesized main) and the per-file body units. extern_indexes name the head pieces whose definitions must become declarations in every unit but the first (the globals), with extern_texts holding those declarations.
struct FastcZygote #
struct FastcZygote {
mut:
fresh FastcZygoteProcess
guess FastcZygoteProcess
guess_feed thread FastcZygoteHead
head_path string
active bool
}
FastcZygote compiles the translation units of a program from one parse of the declarations that they share. A zygote process parses that head and then continues as one process per unit. The compiler forks its zygotes before it generates C, while its own address space is still small: fresh waits for the head of this build, and guess parses the head that the previous build kept in head_path, while this build is generated. When both heads are the same text, the units start from guess without waiting for a parse.
struct FastcZygotePlan #
struct FastcZygotePlan {
pub:
paths []string
mut:
// Unit g is compiled to `<object_prefix>g.o`.
object_prefix string
// unit_items[g] is the first item of unit g; the last entry is the item count.
unit_items []int
// solo_pieces[i] is the first piece of definition item i; the last entry is
// the piece that ends the definitions.
solo_pieces []int
// definitions define what the head declares `extern`, in the first unit.
definitions string
}
FastcZygotePlan groups what the units of a zygote add to the shared head: the program's single definitions and the bodies of its source files. Both are lists of items, the definitions first, and a unit holds consecutive items.
struct GenerationResult #
struct GenerationResult {
pub:
c_pieces []string
source_paths []string
uses_threads bool
c_flags []string
// units describes how c_pieces split into translation units that the
// drivers can compile in parallel (see fastc_write_c_units).
units FastcUnitLayout
// native_symbols names C functions, types and constants referenced by the source graph.
native_symbols []string
// native_declarations retains V's declarations for framework functions hidden by Objective-C headers.
native_declarations map[string]string
}
GenerationResult contains generated C and the complete resolved V source graph. c_pieces is the generated C in output order; every piece is an ordinary owned string, and writing them in sequence (write_c_pieces) or joining them (c_source) yields the program.
fn (GenerationResult) c_source #
fn (g &GenerationResult) c_source() string
c_source joins the generated C pieces into one string.
fn (GenerationResult) c_size #
fn (g &GenerationResult) c_size() int
c_size returns the size of the generated C in bytes.
- README
- fn fastc_add_prepared_link_input
- fn fastc_begin_feed_prestarted_c_units
- fn fastc_begin_native_compile
- fn fastc_begin_render_c_units
- fn fastc_begin_render_prestarted_c_units
- fn fastc_codesign_shim_dir
- fn fastc_compile_c_unit_texts
- fn fastc_compile_c_units
- fn fastc_compile_prestarted_rendering_c_units
- fn fastc_compile_rendering_c_units
- fn fastc_compile_zygote_c_units
- fn fastc_discard_link
- fn fastc_discard_native_compile
- fn fastc_discard_prestarted_c_units
- fn fastc_discard_zygote
- fn fastc_finish_link
- fn fastc_finish_native_compile
- fn fastc_finish_prestarted_c_units
- fn fastc_finish_render_c_units
- fn fastc_flag_is_native_input
- fn fastc_generation_link_cache_key
- fn fastc_link_cache_key
- fn fastc_macos_system_tbd
- fn fastc_native_args_adapter
- fn fastc_payload_object
- fn fastc_prepare_c_units
- fn fastc_prepare_link
- fn fastc_prepared_link_accepts_inputs
- fn fastc_prepared_link_skips_codesign
- fn fastc_prestart_c_units
- fn fastc_prestarted_c_units_match
- fn fastc_publish_link_cache
- fn fastc_remove_c_units
- fn fastc_remove_codesign_shim_dir
- fn fastc_render_c_units
- fn fastc_restore_link_cache
- fn fastc_run_command
- fn fastc_sign_macho_adhoc
- fn fastc_split_payload_unit
- fn fastc_start_zygote
- fn fastc_tcc_job_count
- fn fastc_write_c_units
- fn fastc_zygote_accepts
- fn fastc_zygote_head_path
- fn fastc_zygote_plan
- fn fastc_zygote_unit_limit
- fn generate
- fn generate_files
- fn generate_files_with_native_aliases
- fn generate_files_with_source_paths
- fn write_c_pieces
- type FastcCodesignShim
- struct FastcFeedingCUnits
- struct FastcNativeArgsAdapter
- struct FastcNativeCompile
- struct FastcPayloadObject
- struct FastcPayloadUnit
- struct FastcPreparedLink
- struct FastcPreparedUnits
- struct FastcPrestartedCUnits
- struct FastcRenderedCUnits
- struct FastcRenderingCUnits
- struct FastcUnitLayout
- struct FastcZygote
- struct FastcZygotePlan
- struct GenerationResult