Remove support for the builtin_script_t feature

This was an old experiment to compile scripts directly into the
shell itself, reducing the amount of I/O performed at startup.
It has not been used for a long time. Time to remove it.
This commit is contained in:
ridiculousfish 2017-01-29 21:34:30 -08:00
parent 6db372133d
commit e8d90dbf4b
2 changed files with 60 additions and 111 deletions

View file

@ -47,12 +47,9 @@ file_access_attempt_t access_file(const wcstring &path, int mode) {
} }
autoload_t::autoload_t(const wcstring &env_var_name_var, autoload_t::autoload_t(const wcstring &env_var_name_var,
command_removed_function_t cmd_removed_callback, command_removed_function_t cmd_removed_callback)
const builtin_script_t *const scripts, size_t script_count)
: lock(), : lock(),
env_var_name(env_var_name_var), env_var_name(env_var_name_var),
builtin_scripts(scripts),
builtin_script_count(script_count),
command_removed(cmd_removed_callback) { command_removed(cmd_removed_callback) {
pthread_mutex_init(&lock, NULL); pthread_mutex_init(&lock, NULL);
} }
@ -123,11 +120,6 @@ bool autoload_t::can_load(const wcstring &cmd, const env_vars_snapshot_t &vars)
return this->locate_file_and_maybe_load_it(cmd, false, false, path_list); return this->locate_file_and_maybe_load_it(cmd, false, false, path_list);
} }
static bool script_name_precedes_script_name(const builtin_script_t &script1,
const builtin_script_t &script2) {
return wcscmp(script1.name, script2.name) < 0;
}
/// Check whether the given command is loaded. /// Check whether the given command is loaded.
bool autoload_t::has_tried_loading(const wcstring &cmd) { bool autoload_t::has_tried_loading(const wcstring &cmd) {
scoped_lock locker(lock); scoped_lock locker(lock);
@ -201,110 +193,78 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
// The source of the script will end up here. // The source of the script will end up here.
wcstring script_source; wcstring script_source;
bool has_script_source = false;
// Whether we found an accessible file. // Whether we found an accessible file.
bool found_file = false; bool found_file = false;
// Look for built-in scripts via a binary search. // Iterate over path searching for suitable completion files.
const builtin_script_t *matching_builtin_script = NULL; for (size_t i = 0; i < path_list.size() && !found_file; i++) {
if (builtin_script_count > 0) { wcstring next = path_list.at(i);
const builtin_script_t test_script = {cmd.c_str(), NULL}; wcstring path = next + L"/" + cmd + L".fish";
const builtin_script_t *array_end = builtin_scripts + builtin_script_count;
const builtin_script_t *found = std::lower_bound(builtin_scripts, array_end, test_script,
script_name_precedes_script_name);
if (found != array_end && !wcscmp(found->name, test_script.name)) {
matching_builtin_script = found;
}
}
if (matching_builtin_script) {
has_script_source = true;
script_source = str2wcstring(matching_builtin_script->def);
// Make a node representing this function. const file_access_attempt_t access = access_file(path, R_OK);
if (!access.accessible) {
continue;
}
// Now we're actually going to take the lock.
scoped_lock locker(lock); scoped_lock locker(lock);
autoload_function_t *func = this->get_autoloaded_function_with_creation(cmd, really_load); autoload_function_t *func = this->get(cmd);
// This function is internalized. // Generate the source if we need to load it.
func->is_internalized = true; bool need_to_load_function =
really_load &&
(func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
if (need_to_load_function) {
// Generate the script source.
script_source = L"source " + escape_string(path, ESCAPE_ALL);
// It's a fiction to say the script is loaded at this point, but we're definitely going to // Remove any loaded command because we are going to reload it. Note that this
// load it down below. // will deadlock if command_removed calls back into us.
if (really_load) func->is_loaded = true; if (func && func->is_loaded) {
command_removed(cmd);
func->is_placeholder = false;
}
// Mark that we're reloading it.
reloaded = true;
}
// Create the function if we haven't yet. This does not load it. Do not trigger
// eviction unless we are actually loading, because we don't want to evict off of
// the main thread.
if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
// It's a fiction to say the script is loaded at this point, but we're definitely
// going to load it down below.
if (need_to_load_function) func->is_loaded = true;
// Unconditionally record our access time.
func->access = access;
found_file = true;
} }
if (!has_script_source) { // If no file or builtin script was found we insert a placeholder function. Later we only
// Iterate over path searching for suitable completion files. // research if the current time is at least five seconds later. This way, the files won't be
for (size_t i = 0; i < path_list.size() && !found_file; i++) { // searched over and over again.
wcstring next = path_list.at(i); if (!found_file && script_source.empty()) {
wcstring path = next + L"/" + cmd + L".fish"; scoped_lock locker(lock);
// Generate a placeholder.
const file_access_attempt_t access = access_file(path, R_OK); autoload_function_t *func = this->get(cmd);
if (!access.accessible) { if (!func) {
continue; if (really_load) {
this->insert(cmd, autoload_function_t(true));
} else {
this->insert(cmd, autoload_function_t(true));
} }
func = this->get(cmd);
// Now we're actually going to take the lock. assert(func);
scoped_lock locker(lock);
autoload_function_t *func = this->get(cmd);
// Generate the source if we need to load it.
bool need_to_load_function =
really_load &&
(func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
if (need_to_load_function) {
// Generate the script source.
wcstring esc = escape_string(path, 1);
script_source = L"source " + esc;
has_script_source = true;
// Remove any loaded command because we are going to reload it. Note that this
// will deadlock if command_removed calls back into us.
if (func && func->is_loaded) {
command_removed(cmd);
func->is_placeholder = false;
}
// Mark that we're reloading it.
reloaded = true;
}
// Create the function if we haven't yet. This does not load it. Do not trigger
// eviction unless we are actually loading, because we don't want to evict off of
// the main thread.
if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
// It's a fiction to say the script is loaded at this point, but we're definitely
// going to load it down below.
if (need_to_load_function) func->is_loaded = true;
// Unconditionally record our access time.
func->access = access;
found_file = true;
}
// If no file or builtin script was found we insert a placeholder function. Later we only
// research if the current time is at least five seconds later. This way, the files won't be
// searched over and over again.
if (!found_file && !has_script_source) {
scoped_lock locker(lock);
// Generate a placeholder.
autoload_function_t *func = this->get(cmd);
if (!func) {
if (really_load) {
this->insert(cmd, autoload_function_t(true));
} else {
this->insert(cmd, autoload_function_t(true));
}
func = this->get(cmd);
assert(func);
}
func->access.last_checked = time(NULL);
} }
func->access.last_checked = time(NULL);
} }
// If we have a script, either built-in or a file source, then run it. // If we have a script, either built-in or a file source, then run it.
if (really_load && has_script_source) { if (really_load && !script_source.empty()) {
// Do nothing on failure. // Do nothing on failure.
exec_subshell(script_source, false /* do not apply exit status */); exec_subshell(script_source, false /* do not apply exit status */);
} }
@ -313,5 +273,5 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
return reloaded; return reloaded;
} }
return found_file || has_script_source; return found_file || !script_source.empty();
} }

View file

@ -40,11 +40,6 @@ struct autoload_function_t {
bool is_internalized; bool is_internalized;
}; };
struct builtin_script_t {
const wchar_t *name;
const char *def;
};
class env_vars_snapshot_t; class env_vars_snapshot_t;
/// Class representing a path from which we can autoload and the autoloaded contents. /// Class representing a path from which we can autoload and the autoloaded contents.
@ -54,10 +49,6 @@ class autoload_t : public lru_cache_t<autoload_t, autoload_function_t> {
pthread_mutex_t lock; pthread_mutex_t lock;
/// The environment variable name. /// The environment variable name.
const wcstring env_var_name; const wcstring env_var_name;
/// Builtin script array.
const struct builtin_script_t *const builtin_scripts;
/// Builtin script count.
const size_t builtin_script_count;
/// The path from which we most recently autoloaded. /// The path from which we most recently autoloaded.
wcstring last_path; wcstring last_path;
/// the most reecently autoloaded path, tokenized (split on separators). /// the most reecently autoloaded path, tokenized (split on separators).
@ -83,9 +74,7 @@ class autoload_t : public lru_cache_t<autoload_t, autoload_function_t> {
// Create an autoload_t for the given environment variable name. // Create an autoload_t for the given environment variable name.
autoload_t(const wcstring &env_var_name_var, autoload_t(const wcstring &env_var_name_var,
command_removed_function_t callback, command_removed_function_t callback);
const builtin_script_t *scripts = NULL,
size_t script_count = 0);
~autoload_t(); ~autoload_t();