The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #12700 from xavierleroy/gen-prims

Generate runtime/prims.c with the correct types in primitive declarations

authored by

Xavier Leroy and committed by
GitHub
217d42e7 8cc728b5

+113 -69
+4
Changes
··· 149 149 `CAMLprim`, or remove them entirely if no longer used. 150 150 (Xavier Leroy, review by David Allsopp) 151 151 152 + - #12700, continuing #11763 and trying to address #12660: 153 + Use the correct types for primitives when generating the table of primitives 154 + used by ocamlrun. 155 + (Xavier Leroy, motivation, review and improvements by Antonin Décimo) 152 156 153 157 ### Code generation and optimizations: 154 158
+8 -37
Makefile
··· 1251 1251 $(V_GEN)echo "$(STUBLIBDIR)" > $@ && \ 1252 1252 echo "$(LIBDIR)" >> $@ 1253 1253 1254 - # If primitives contain duplicated lines (e.g. because the code is defined 1255 - # like 1256 - # #ifdef X 1257 - # CAMLprim value caml_foo() ... 1258 - # #else 1259 - # CAMLprim value caml_foo() ... 1260 - # #endif), horrible things will happen: duplicated entries in Runtimedef -> 1261 - # double registration in Symtable -> empty entry in the PRIM table -> 1262 - # the bytecode interpreter is confused. 1263 - # We sort the primitive file and remove duplicates to avoid this problem. 1264 - 1265 - # Warning: we use "sort | uniq" instead of "sort -u" because in the MSVC 1266 - # port, the "sort" program in the path is Microsoft's and not cygwin's 1267 - 1268 - # Warning: POSIX sort is locale dependent, that's why we set LC_ALL explicitly. 1269 - # Sort is unstable for "is_directory" and "isatty" 1270 - # see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html: 1271 - # "using sort to process pathnames, it is recommended that LC_ALL .. set to C" 1272 - 1273 1254 # To speed up builds, we avoid changing "primitives" when files 1274 1255 # containing primitives change but the primitives table does not 1275 - runtime/primitives: \ 1276 - $(shell runtime/gen_primitives.sh > runtime/primitives.new; \ 1256 + runtime/primitives: runtime/gen_primitives.sh \ 1257 + $(shell runtime/gen_primitives.sh $(runtime_BYTECODE_C_SOURCES) \ 1258 + > runtime/primitives.new; \ 1277 1259 cmp -s runtime/primitives runtime/primitives.new || \ 1278 1260 echo runtime/primitives.new) 1279 - $(V_GEN)cp $^ $@ 1261 + $(V_GEN)cp runtime/primitives.new $@ 1280 1262 1281 - runtime/prims.c : runtime/primitives 1282 - $(V_GEN)export LC_ALL=C; \ 1283 - (echo '#include "caml/config.h"'; \ 1284 - echo 'typedef intnat value;'; \ 1285 - echo 'typedef value (*c_primitive)(void);'; \ 1286 - echo; \ 1287 - sed -e 's/.*/extern value &(void);/' $<; \ 1288 - echo; \ 1289 - echo 'const c_primitive caml_builtin_cprim[] = {'; \ 1290 - sed -e 's/.*/ &,/' $<; \ 1291 - echo ' 0 };'; \ 1292 - echo; \ 1293 - echo 'const char * const caml_names_of_builtin_cprim[] = {'; \ 1294 - sed -e 's/.*/ "&",/' $<; \ 1295 - echo ' 0 };') > $@ 1263 + runtime/prims.c: runtime/gen_primsc.sh runtime/primitives 1264 + $(V_GEN)runtime/gen_primsc.sh \ 1265 + runtime/primitives $(runtime_BYTECODE_C_SOURCES) \ 1266 + > $@ 1296 1267 1297 1268 runtime/caml/opnames.h : runtime/caml/instruct.h 1298 1269 $(V_GEN)tr -d '\r' < $< | \
+4 -3
runtime/dune
··· 13 13 ;************************************************************************** 14 14 15 15 (rule 16 - (targets primitives) 16 + (targets primitives prims.c) 17 17 (mode fallback) 18 18 (deps 19 19 ; matches the line structure of files in gen_primitives.sh ··· 25 25 runtime_events.c sync.c 26 26 dynlink.c backtrace_byt.c backtrace.c afl.c bigarray.c prng.c) 27 27 (action 28 - (chdir .. 29 - (with-stdout-to %{targets} (run %{dep:gen_primitives.sh}))))) 28 + (progn 29 + (with-stdout-to primitives (run %{dep:gen_primitives.sh} %{deps})) 30 + (with-stdout-to prims.c (run %{dep:gen_primsc.sh} primitives %{deps}))))) 30 31 31 32 (rule 32 33 (targets libcamlrun.a)
+9 -15
runtime/floats.c
··· 1100 1100 return caml_signbit(Double_val(f)); 1101 1101 } 1102 1102 1103 - CAMLprim value caml_neq_float(value f, value g) 1104 - { 1105 - return Val_bool(Double_val(f) != Double_val(g)); 1106 - } 1107 - 1108 - #define DEFINE_NAN_CMP(op) (value f, value g) \ 1109 - { \ 1110 - return Val_bool(Double_val(f) op Double_val(g)); \ 1111 - } 1112 - 1113 1103 intnat caml_float_compare_unboxed(double f, double g) 1114 1104 { 1115 1105 /* If one or both of f and g is NaN, order according to the convention ··· 1124 1114 return res; 1125 1115 } 1126 1116 1127 - CAMLprim value caml_eq_float DEFINE_NAN_CMP(==) 1128 - CAMLprim value caml_le_float DEFINE_NAN_CMP(<=) 1129 - CAMLprim value caml_lt_float DEFINE_NAN_CMP(<) 1130 - CAMLprim value caml_ge_float DEFINE_NAN_CMP(>=) 1131 - CAMLprim value caml_gt_float DEFINE_NAN_CMP(>) 1117 + #define FLOAT_CMP(op, f, g) \ 1118 + return Val_bool(Double_val(f) op Double_val(g)); 1119 + 1120 + CAMLprim value caml_neq_float(value f, value g) { FLOAT_CMP(!=, f, g) } 1121 + CAMLprim value caml_eq_float(value f, value g) { FLOAT_CMP(==, f, g) } 1122 + CAMLprim value caml_le_float(value f, value g) { FLOAT_CMP(<=, f, g) } 1123 + CAMLprim value caml_lt_float(value f, value g) { FLOAT_CMP(<, f, g) } 1124 + CAMLprim value caml_ge_float(value f, value g) { FLOAT_CMP(>=, f, g) } 1125 + CAMLprim value caml_gt_float(value f, value g) { FLOAT_CMP(>, f, g) } 1132 1126 1133 1127 CAMLprim value caml_float_compare(value vf, value vg) 1134 1128 {
+25 -14
runtime/gen_primitives.sh
··· 15 15 #* * 16 16 #************************************************************************** 17 17 18 - # #8985: the meaning of character range a-z depends on the locale, so force C 19 - # locale throughout. 18 + # If primitives contain duplicated lines (e.g. because the code is defined 19 + # like 20 + # #ifdef X 21 + # CAMLprim value caml_foo() ... 22 + # #else 23 + # CAMLprim value caml_foo() ... 24 + # #endif), horrible things will happen: duplicated entries in Runtimedef -> 25 + # double registration in Symtable -> empty entry in the PRIM table -> 26 + # the bytecode interpreter is confused. 27 + # We sort the primitive file and remove duplicates to avoid this problem. 28 + 29 + # Warning: we use "sort | uniq" instead of "sort -u" because in the MSVC 30 + # port, the "sort" program in the path is Microsoft's and not cygwin's 31 + 32 + # Warning: POSIX sort is locale dependent, that's why we set LC_ALL explicitly. 33 + # Sort is unstable for "is_directory" and "isatty" 34 + # see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html: 35 + # "using sort to process pathnames, it is recommended that LC_ALL .. set to C" 36 + 37 + # #8985: in sed, the meaning of character range a-z depends on the locale, 38 + # so force C locale throughout. 39 + 20 40 export LC_ALL=C 21 - ( 22 - for prim in \ 23 - alloc array compare extern floats gc_ctrl hash intern interp ints io \ 24 - lexing md5 meta memprof obj parsing signals str sys callback weak \ 25 - finalise domain platform fiber memory startup_aux runtime_events sync \ 26 - dynlink backtrace_byt backtrace afl \ 27 - bigarray prng 28 - do 29 - sed -n -e 's/^CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p' \ 30 - "runtime/$prim.c" 31 - done 32 - ) | sort | uniq 41 + 42 + sed -n -e 's/^CAMLprim value \([a-z][a-z0-9_]*\).*$/\1/p' "$@" | \ 43 + sort | uniq
+63
runtime/gen_primsc.sh
··· 1 + #!/bin/sh 2 + 3 + #************************************************************************** 4 + #* * 5 + #* OCaml * 6 + #* * 7 + #* Xavier Leroy, Collège de France and Inria * 8 + #* * 9 + #* Copyright 2023 Institut National de Recherche en Informatique et * 10 + #* en Automatique. * 11 + #* * 12 + #* All rights reserved. This file is distributed under the terms of * 13 + #* the GNU Lesser General Public License version 2.1, with the * 14 + #* special exception on linking described in the file LICENSE. * 15 + #* * 16 + #************************************************************************** 17 + 18 + # Build the runtime/prims.c file, with proper C declarations of the primitives 19 + 20 + export LC_ALL=C 21 + 22 + case $# in 23 + 0) echo "Usage: gen_primsc.sh <primitives file> <.c files>" 1>&2 24 + exit 2;; 25 + *) primitives="$1"; shift;; 26 + esac 27 + 28 + cat <<'EOF' 29 + /* Generated file, do not edit */ 30 + 31 + #define CAML_INTERNALS 32 + #include "caml/mlvalues.h" 33 + #include "caml/prims.h" 34 + 35 + EOF 36 + 37 + # Extract the beginning of primitive definitions: 38 + # from 'CAMLprim' at beginning of line to the first closing parenthesis. 39 + # The first pattern below matches single-line definitions such as 40 + # CAMLprim value foo(value x) { 41 + # The second pattern matches multi-line definitions such as 42 + # CAMLprim value foo(value x, 43 + # value y) 44 + sed -n \ 45 + -e '/^CAMLprim value .*)/p' \ 46 + -e '/^CAMLprim value [^)]*$/,/)/p' \ 47 + "$@" | 48 + # Transform these definitions into "CAMLextern" declarations 49 + sed \ 50 + -e 's/^CAMLprim /CAMLextern /' \ 51 + -e 's/).*$/);/' 52 + 53 + # Generate the table of primitives 54 + echo 55 + echo 'const c_primitive caml_builtin_cprim[] = {' 56 + sed -e 's/.*/ (c_primitive) &,/' "$primitives" 57 + echo ' 0 };' 58 + 59 + # Generate the table of primitive names 60 + echo 61 + echo 'const char * const caml_names_of_builtin_cprim[] = {' 62 + sed -e 's/.*/ "&",/' "$primitives" 63 + echo ' 0 };'