#include "bytecode.h"
#include "atimer.h"
#include "window.h"
+#include "dynlib.h"
#define DEFAULT_SPEED 2 /* See comp-speed var. */
define_add1_sub1 ();
define_negate ();
- gcc_jit_context_new_global (comp.ctxt,
- NULL,
- GCC_JIT_GLOBAL_EXPORTED,
- comp.int_type,
- "native_compiled_emacs_lisp");
return Qt;
}
gcc_jit_context_dump_to_file (comp.ctxt, filename, 1);
}
- AUTO_STRING (dot_so, ".so"); /* FIXME use correct var */
+ AUTO_STRING (dot_so, NATIVE_ELISP_SUFFIX);
const char *filename =
(const char *) SDATA (CALLN (Fconcat, ctxtname, dot_so));
{
}
+\f
+
+/************************************/
+/* Native compiler load functions. */
+/************************************/
+
+typedef char *(*comp_litt_str_func) (void);
+
+static Lisp_Object
+comp_retrive_obj (dynlib_handle_ptr handle, const char *str_name)
+{
+ comp_litt_str_func f = dynlib_sym (handle, str_name);
+ char *res = f();
+ return Fread (build_string (res));
+}
+
+static int
+load_comp_unit (dynlib_handle_ptr handle)
+{
+ Lisp_Object *data_relocs = dynlib_sym (handle, "data_relocs");
+
+ Lisp_Object d_vec = comp_retrive_obj (handle, "text_data_relocs");
+ EMACS_UINT d_vec_len = XFIXNUM (Flength (d_vec));
+
+ for (EMACS_UINT i = 0; i < d_vec_len; i++)
+ data_relocs[i] = AREF (d_vec, i);
+
+ Lisp_Object func_list = comp_retrive_obj (handle, "text_funcs");
+
+ while (func_list)
+ {
+ Lisp_Object el = XCAR (func_list);
+ Lisp_Object Qsym = AREF (el, 0);
+ char *c_func_name = SSDATA (AREF (el, 1));
+ Lisp_Object args = AREF (el, 2);
+ ptrdiff_t minargs = XFIXNUM (XCAR (args));
+ ptrdiff_t maxargs = FIXNUMP (XCDR (args)) ? XFIXNUM (XCDR (args)) : MANY;
+ /* char *doc = SSDATA (AREF (el, 3)); */
+ void *func = dynlib_sym (handle, c_func_name);
+ eassert (func);
+
+ union Aligned_Lisp_Subr *x = xmalloc (sizeof (union Aligned_Lisp_Subr));
+ x->s.header.size = PVEC_SUBR << PSEUDOVECTOR_AREA_BITS;
+ x->s.function.a0 = func;
+ x->s.min_args = minargs;
+ x->s.max_args = maxargs;
+ x->s.symbol_name = SSDATA (Fsymbol_name (Qsym));
+ defsubr(x);
+
+ func_list = XCDR (func_list);
+ }
+
+ return 0;
+}
+
+/* Load related routines. */
+DEFUN ("native-elisp-load", Fnative_elisp_load, Snative_elisp_load, 1, 1, 0,
+ doc: /* Load native elisp code FILE. */)
+ (Lisp_Object file)
+{
+ dynlib_handle_ptr handle;
+
+ CHECK_STRING (file);
+ handle = dynlib_open (SSDATA (file));
+ if (!handle)
+ xsignal2 (Qcomp_unit_open_failed, file, build_string (dynlib_error ()));
+
+ int r = load_comp_unit (handle);
+
+ if (r != 0)
+ xsignal2 (Qcomp_unit_init_failed, file, INT_TO_INTEGER (r));
+
+ return Qt;
+}
+
\f
void
syms_of_comp (void)
DEFSYM (Qnegate, "negate");
DEFSYM (QFnumberp, "Fnumberp");
DEFSYM (QFintegerp, "Fintegerp");
+ /* Returned values. */
+ DEFSYM (Qcomp_unit_open_failed, "comp-unit-open-failed");
+ DEFSYM (Qcomp_unit_init_failed, "comp-unit-init-failed");
defsubr (&Scomp__init_ctxt);
defsubr (&Scomp__release_ctxt);
defsubr (&Scomp__add_func_to_ctxt);
defsubr (&Scomp__compile_ctxt_to_file);
+ defsubr (&Snative_elisp_load);
staticpro (&comp.func_hash);
comp.func_hash = Qnil;
}
}
-\f
-/*
- Native compiler load functions.
- FIXME: Move away from here.
-*/
-
-typedef char *(*comp_litt_str_func) (void);
-
-static Lisp_Object
-comp_retrive_obj (dynlib_handle_ptr handle, const char *str_name)
-{
- comp_litt_str_func f = dynlib_sym (handle, str_name);
- char *res = f();
- return Fread (build_string (res));
-}
-
-static int
-comp_load_unit (dynlib_handle_ptr handle, emacs_env *env)
-{
- Lisp_Object *data_relocs = dynlib_sym (handle, "data_relocs");
-
- Lisp_Object d_vec = comp_retrive_obj (handle, "text_data_relocs");
- EMACS_UINT d_vec_len = XFIXNUM (Flength (d_vec));
-
- for (EMACS_UINT i = 0; i < d_vec_len; i++)
- data_relocs[i] = AREF (d_vec, i);
-
- Lisp_Object func_list = comp_retrive_obj (handle, "text_funcs");
-
- while (func_list)
- {
- Lisp_Object el = XCAR (func_list);
- Lisp_Object Qsym = AREF (el, 0);
- char *c_func_name = SSDATA (AREF (el, 1));
- Lisp_Object args = AREF (el, 2);
- ptrdiff_t minargs = XFIXNUM (XCAR (args));
- ptrdiff_t maxargs = FIXNUMP (XCDR (args)) ? XFIXNUM (XCDR (args)) : MANY;
- /* char *doc = SSDATA (AREF (el, 3)); */
- void *func = dynlib_sym (handle, c_func_name);
- eassert (func);
- /* Ffset (Qsym, */
- /* value_to_lisp (module_make_function (env, minargs, maxargs, func, */
- /* doc, NULL))); */
-
- union Aligned_Lisp_Subr *x = xmalloc (sizeof (union Aligned_Lisp_Subr));
- x->s.header.size = PVEC_SUBR << PSEUDOVECTOR_AREA_BITS;
- x->s.function.a0 = func;
- x->s.min_args = minargs;
- x->s.max_args = maxargs;
- x->s.symbol_name = SSDATA (Fsymbol_name (Qsym));
- defsubr(x);
-
- func_list = XCDR (func_list);
- }
-
- return 0;
-}
-
/* Live runtime and environment objects, for assertions. */
static Lisp_Object Vmodule_runtimes;
static Lisp_Object Vmodule_environments;
{
dynlib_handle_ptr handle;
emacs_init_function module_init;
- void *gpl_sym, *native_comp;
+ void *gpl_sym;
CHECK_STRING (file);
handle = dynlib_open (SSDATA (file));
xsignal2 (Qmodule_open_failed, file, build_string (dynlib_error ()));
gpl_sym = dynlib_sym (handle, "plugin_is_GPL_compatible");
- native_comp = dynlib_sym (handle, "native_compiled_emacs_lisp");
- if (!gpl_sym && !native_comp)
+ if (!gpl_sym)
xsignal1 (Qmodule_not_gpl_compatible, file);
- if (!native_comp)
- {
- module_init =
- (emacs_init_function) dynlib_func (handle, "emacs_module_init");
- if (!module_init)
- xsignal1 (Qmissing_module_init_function, file);
- }
+ module_init = (emacs_init_function) dynlib_func (handle, "emacs_module_init");
+ if (!module_init)
+ xsignal1 (Qmissing_module_init_function, file);
+
struct emacs_runtime rt_pub;
struct emacs_runtime_private rt_priv;
emacs_env env_pub;
ptrdiff_t count = SPECPDL_INDEX ();
record_unwind_protect_ptr (finalize_runtime_unwind, rt);
- int r = native_comp ? comp_load_unit (handle, &env_pub) : module_init (rt);
+ int r = module_init (rt);
/* Process the quit flag first, so that quitting doesn't get
overridden by other non-local exits. */
bool is_module = false;
#endif
+#ifdef HAVE_LIBGCCJIT
+ bool is_native_elisp = suffix_p (found, NATIVE_ELISP_SUFFIX);
+#else
+ bool is_native_elisp = false;
+#endif
/* Check if we're stuck in a recursive load cycle.
2000-09-21: It's not possible to just check for the file loaded
} /* !load_prefer_newer */
}
}
- else if (!is_module)
+ else if (!is_module && !is_native_elisp)
{
/* We are loading a source file (*.el). */
if (!NILP (Vload_source_file_function))
stream = NULL;
errno = EINVAL;
}
- else if (!is_module)
+ else if (!is_module && !is_native_elisp)
{
#ifdef WINDOWSNT
emacs_close (fd);
might be accessed by the unbind_to call below. */
struct infile input;
- if (is_module)
+ if (is_module || is_native_elisp)
{
/* `module-load' uses the file name, so we can close the stream
now. */
file, 1);
else if (is_module)
message_with_string ("Loading %s (module)...", file, 1);
+ else if (is_native_elisp)
+ message_with_string ("Loading %s (native compiled elisp)...", file, 1);
else if (!compiled)
message_with_string ("Loading %s (source)...", file, 1);
else if (newer)
#else
/* This cannot happen. */
emacs_abort ();
+#endif
+ }
+ else if (is_native_elisp)
+ {
+#ifdef HAVE_LIBGCCJIT
+ specbind (Qcurrent_load_list, Qnil);
+ LOADHIST_ATTACH (found);
+ Fnative_elisp_load (found);
+ build_load_history (found, true);
+#else
+ /* This cannot happen. */
+ emacs_abort ();
#endif
}
else
This list should not include the empty string.
`load' and related functions try to append these suffixes, in order,
to the specified file name if a suffix is allowed or required. */);
+ Vload_suffixes = list2 (build_pure_c_string (".elc"),
+ build_pure_c_string (".el"));
#ifdef HAVE_MODULES
+ Vload_suffixes = Fcons (build_pure_c_string (MODULES_SUFFIX), Vload_suffixes);
#ifdef MODULES_SECONDARY_SUFFIX
- Vload_suffixes = list4 (build_pure_c_string (".elc"),
- build_pure_c_string (".el"),
- build_pure_c_string (MODULES_SUFFIX),
- build_pure_c_string (MODULES_SECONDARY_SUFFIX));
-#else
- Vload_suffixes = list3 (build_pure_c_string (".elc"),
- build_pure_c_string (".el"),
- build_pure_c_string (MODULES_SUFFIX));
+ Vload_suffixes =
+ Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes);
#endif
-#else
- Vload_suffixes = list2 (build_pure_c_string (".elc"),
- build_pure_c_string (".el"));
#endif
+#ifdef HAVE_LIBGCCJIT
+ Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), Vload_suffixes);
+#endif
+
DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix,
doc: /* Suffix of loadable module file, or nil if modules are not supported. */);
#ifdef HAVE_MODULES