aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/utils/make_driver_tab
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/utils/make_driver_tab')
-rwxr-xr-xerts/emulator/utils/make_driver_tab95
1 files changed, 91 insertions, 4 deletions
diff --git a/erts/emulator/utils/make_driver_tab b/erts/emulator/utils/make_driver_tab
index fbbfa3e49e..3eedef21a7 100755
--- a/erts/emulator/utils/make_driver_tab
+++ b/erts/emulator/utils/make_driver_tab
@@ -27,7 +27,11 @@ use File::Basename;
# usage: make_driver_tab [-o filename] drivers...
my $file = "";
-my @drivers = ();
+my $nif = "";
+my @emu_drivers = ();
+my @static_drivers = ();
+my @nifs = ();
+my $mode = 1;
while (@ARGV) {
my $d = shift;
@@ -35,9 +39,28 @@ while (@ARGV) {
$file = shift or die("-o requires argument");
next;
}
+ if ( $d =~ /^-nifs$/ ) {
+ $mode = 2;
+ next;
+ }
+ if ( $d =~ /^-drivers$/ ) {
+ $mode = 1;
+ next;
+ }
+ if ( $d =~ /^.*\.a$/ ) {
+ $d = basename $d;
+ $d =~ s/\.a$//; # strip .a
+ if ($mode == 1) {
+ push(@static_drivers, $d);
+ }
+ if ($mode == 2) {
+ push(@nifs, $d);
+ }
+ next;
+ }
$d = basename $d;
$d =~ s/drv(\..*|)$//; # strip drv.* or just drv
- push(@drivers, $d);
+ push(@emu_drivers, $d);
}
# Did we want output to a file?
@@ -52,20 +75,84 @@ print <<EOF;
#include <stdio.h>
#include "global.h"
+
EOF
# "extern" declarations
-foreach (@drivers) {
+foreach (@emu_drivers) {
print "extern ErlDrvEntry ${_}driver_entry;\n";
}
+foreach (@static_drivers) {
+ print "ErlDrvEntry *${_}_driver_init(void);\n";
+}
+
# The array itself
print "\nErlDrvEntry *driver_tab[DRIVER_TAB_SIZE] =\n{\n";
-foreach (@drivers) {
+foreach (@emu_drivers) {
print " &${_}driver_entry,\n";
}
+foreach (@static_drivers) {
+ print " NULL, /* ${_} */\n";
+}
print " NULL\n};\n";
+print "void erts_init_static_drivers() {\n";
+
+my $index = 0;
+foreach (@static_drivers) {
+ print " driver_tab[".(scalar @emu_drivers+$index)."] = ${_}_driver_init();\n";
+ $index++;
+}
+
+print "}\n";
+
+print <<EOF;
+
+typedef struct ErtsStaticNifEntry_ {
+ const char *nif_name;
+ ErtsStaticNifInitFPtr nif_init;
+} ErtsStaticNifEntry;
+
+EOF
+
+# prototypes
+foreach (@nifs) {
+ my $d = ${_};
+ $d =~ s/\.debug//; # strip .debug
+ print "void *".$d."_nif_init(void);\n";
+}
+
+# The array itself
+print "static ErtsStaticNifEntry static_nif_tab[DRIVER_TAB_SIZE] =\n{\n";
+
+foreach (@nifs) {
+ my $d = ${_};
+ $d =~ s/\.debug//; # strip .debug
+ print "{\"${_}\",&".$d."_nif_init},\n";
+}
+
+print " {NULL,NULL}\n};\n";
+
+print <<EOF;
+ErtsStaticNifInitFPtr erts_static_nif_get_nif_init(const char *name) {
+ int i;
+ for (i = 0; static_nif_tab[i].nif_name != NULL; i++)
+ if (strcmp(name,static_nif_tab[i].nif_name) == 0)
+ return static_nif_tab[i].nif_init;
+ return NULL;
+}
+
+int erts_is_static_nif(void *handle) {
+ int i;
+ for (i = 0; static_nif_tab[i].nif_name != NULL; i++)
+ if (((void*)static_nif_tab[i].nif_init) == handle)
+ return 1;
+ return 0;
+}
+
+EOF
+
# That's it