git: 9c8bf69a53f6 - main - loader: Only create gfx 4th bindings when gfx is available

From: Warner Losh <imp_at_FreeBSD.org>
Date: Fri, 16 Feb 2024 04:00:26 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9c8bf69a53f628b62fb196182ea55fb34c1c19e1

commit 9c8bf69a53f628b62fb196182ea55fb34c1c19e1
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-16 03:53:28 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-02-16 03:59:22 +0000

    loader: Only create gfx 4th bindings when gfx is available
    
    Only create the gfx bindings for 4th when it's compiled into the
    loader. We do this with a linker set that only gets brought in to those
    loaders that call gfx_framework_init. This calls gfx_interp_md() will
    will drag in gfx_loader.c which will add to the linker set that
    registers these bindings.
    
    Sponsored by:           Netflix
    Reviewed by:            kevans, jhb
    Differential Revision:  https://reviews.freebsd.org/D43904
---
 stand/common/gfx_fb.c   |   1 +
 stand/ficl/Makefile     |   5 +-
 stand/ficl/gfx_loader.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++
 stand/ficl/loader.c     | 188 -----------------------------------
 4 files changed, 263 insertions(+), 190 deletions(-)

diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c
index b61591bf3d45..3a5b851915e0 100644
--- a/stand/common/gfx_fb.c
+++ b/stand/common/gfx_fb.c
@@ -181,6 +181,7 @@ gfx_framework_init(void)
 	 * Setup font list to have builtin font.
 	 */
 	(void) insert_font(NULL, FONT_BUILTIN);
+	gfx_interp_md();	/* Draw in the gfx interpreter for this thing */
 }
 
 static uint8_t *
diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile
index a9b384024667..fe4ee03974b1 100644
--- a/stand/ficl/Makefile
+++ b/stand/ficl/Makefile
@@ -11,8 +11,8 @@ BASE_SRCS=	dict.c ficl.c fileaccess.c float.c loader.c math64.c \
 SRCS=		${BASE_SRCS} sysdep.c softcore.c
 CLEANFILES+=	softcore.c testmain testmain.o
 
-CFLAGS.loader.c += -I${SRCTOP}/sys/teken
-CFLAGS.loader.c += -I${SRCTOP}/contrib/pnglite
+CFLAGS.gfx_loader.c += -I${SRCTOP}/sys/teken
+CFLAGS.gfx_loader.c += -I${SRCTOP}/contrib/pnglite
 .ifmake testmain
 CFLAGS=	-DTESTMAIN -D_TESTMAIN
 CFLAGS+=	-I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC}
@@ -21,6 +21,7 @@ PROG=		testmain
 .include <bsd.prog.mk>
 .else
 LIB=		ficl
+BASE_SRCS+=	gfx_loader.c	# Not TESTMAINable
 .include <bsd.lib.mk>
 .endif
 
diff --git a/stand/ficl/gfx_loader.c b/stand/ficl/gfx_loader.c
new file mode 100644
index 000000000000..a4501a7d3c39
--- /dev/null
+++ b/stand/ficl/gfx_loader.c
@@ -0,0 +1,259 @@
+/*-
+ * Copyright (c) 2024 Netflix, Inc
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/* Copied from a file that likely shoulve have had this at the top */
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2020 Toomas Soome
+ * Copyright 2020 RackTop Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*******************************************************************
+** g f x _ l o a d e r . c
+** Additional FICL words designed for FreeBSD's loader
+** for graphics
+*******************************************************************/
+
+#include <stand.h>
+#include "bootstrap.h"
+#include <gfx_fb.h>
+#include <pnglite.h>
+#include "ficl.h"
+
+/*		FreeBSD's loader interaction words and extras
+ *		for graphics
+ *		fb-bezier	( x0 y0 x1 y1 x2 y2 wd -- )
+ *		fb-drawrect	( x1 y1 x2 y2 fill -- )
+ *		fb-line		( x0 y0 x1 y1 wd -- )
+ * 		fb-putimage	( flags x1 y1 x2 y2 -- flag )
+ *		fb-setpixel	( x y -- )
+ *		term-drawrect	( x1 y1 x2 y2 fill -- )
+ *		term-putimage	( flags x1 y1 x2 y2 -- flag )
+ */
+
+/* ( flags x1 y1 x2 y2 -- flag ) */
+void
+ficl_term_putimage(FICL_VM *pVM)
+{
+        char *namep, *name;
+        int names;
+        unsigned long ret = FICL_FALSE;
+        uint32_t x1, y1, x2, y2, f;
+        png_t png;
+	int error;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 7, 1);
+#endif
+        names = stackPopINT(pVM->pStack);
+        namep = (char *) stackPopPtr(pVM->pStack);
+        y2 = stackPopINT(pVM->pStack);
+        x2 = stackPopINT(pVM->pStack);
+        y1 = stackPopINT(pVM->pStack);
+        x1 = stackPopINT(pVM->pStack);
+        f = stackPopINT(pVM->pStack);
+
+	x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width;
+	y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height;
+	if (x2 != 0) {
+		x2 = gfx_state.tg_origin.tp_col +
+		    x2 * gfx_state.tg_font.vf_width;
+	}
+	if (y2 != 0) {
+		y2 = gfx_state.tg_origin.tp_row +
+		    y2 * gfx_state.tg_font.vf_height;
+	}
+
+        name = ficlMalloc(names + 1);
+        if (!name)
+		vmThrowErr(pVM, "Error: out of memory");
+        (void) strncpy(name, namep, names);
+        name[names] = '\0';
+
+        if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
+		if (f & FL_PUTIMAGE_DEBUG)
+			printf("%s\n", png_error_string(error));
+	} else {
+                if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
+                        ret = FICL_TRUE;        /* success */
+                (void) png_close(&png);
+	}
+        ficlFree(name);
+	stackPushUNS(pVM->pStack, ret);
+}
+
+/* ( flags x1 y1 x2 y2 -- flag ) */
+void
+ficl_fb_putimage(FICL_VM *pVM)
+{
+        char *namep, *name;
+        int names;
+        unsigned long ret = FICL_FALSE;
+        uint32_t x1, y1, x2, y2, f;
+        png_t png;
+	int error;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 7, 1);
+#endif
+        names = stackPopINT(pVM->pStack);
+        namep = (char *) stackPopPtr(pVM->pStack);
+        y2 = stackPopINT(pVM->pStack);
+        x2 = stackPopINT(pVM->pStack);
+        y1 = stackPopINT(pVM->pStack);
+        x1 = stackPopINT(pVM->pStack);
+        f = stackPopINT(pVM->pStack);
+
+        name = ficlMalloc(names + 1);
+        if (!name)
+		vmThrowErr(pVM, "Error: out of memory");
+        (void) strncpy(name, namep, names);
+        name[names] = '\0';
+
+        if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
+		if (f & FL_PUTIMAGE_DEBUG)
+			printf("%s\n", png_error_string(error));
+	} else {
+                if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
+                        ret = FICL_TRUE;        /* success */
+                (void) png_close(&png);
+	}
+        ficlFree(name);
+	stackPushUNS(pVM->pStack, ret);
+}
+
+void
+ficl_fb_setpixel(FICL_VM *pVM)
+{
+        FICL_UNS x, y;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 2, 0);
+#endif
+
+        y = stackPopUNS(pVM->pStack);
+        x = stackPopUNS(pVM->pStack);
+        gfx_fb_setpixel(x, y);
+}
+
+void
+ficl_fb_line(FICL_VM *pVM)
+{
+	FICL_UNS x0, y0, x1, y1, wd;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 5, 0);
+#endif
+
+	wd = stackPopUNS(pVM->pStack);
+	y1 = stackPopUNS(pVM->pStack);
+	x1 = stackPopUNS(pVM->pStack);
+	y0 = stackPopUNS(pVM->pStack);
+	x0 = stackPopUNS(pVM->pStack);
+	gfx_fb_line(x0, y0, x1, y1, wd);
+}
+
+void
+ficl_fb_bezier(FICL_VM *pVM)
+{
+	FICL_UNS x0, y0, x1, y1, x2, y2, width;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 7, 0);
+#endif
+
+	width = stackPopUNS(pVM->pStack);
+	y2 = stackPopUNS(pVM->pStack);
+	x2 = stackPopUNS(pVM->pStack);
+	y1 = stackPopUNS(pVM->pStack);
+	x1 = stackPopUNS(pVM->pStack);
+	y0 = stackPopUNS(pVM->pStack);
+	x0 = stackPopUNS(pVM->pStack);
+	gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width);
+}
+
+void
+ficl_fb_drawrect(FICL_VM *pVM)
+{
+	FICL_UNS x1, x2, y1, y2, fill;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 5, 0);
+#endif
+
+	fill = stackPopUNS(pVM->pStack);
+	y2 = stackPopUNS(pVM->pStack);
+	x2 = stackPopUNS(pVM->pStack);
+	y1 = stackPopUNS(pVM->pStack);
+	x1 = stackPopUNS(pVM->pStack);
+	gfx_fb_drawrect(x1, y1, x2, y2, fill);
+}
+
+void
+ficl_term_drawrect(FICL_VM *pVM)
+{
+	FICL_UNS x1, x2, y1, y2;
+
+#if FICL_ROBUST > 1
+	vmCheckStack(pVM, 4, 0);
+#endif
+
+	y2 = stackPopUNS(pVM->pStack);
+	x2 = stackPopUNS(pVM->pStack);
+	y1 = stackPopUNS(pVM->pStack);
+	x1 = stackPopUNS(pVM->pStack);
+	gfx_term_drawrect(x1, y1, x2, y2);
+}
+
+/**************************************************************************
+                        f i c l C o m p i l e G f x
+** Build FreeBSD platform extensions into the system dictionary
+** for gfx
+**************************************************************************/
+static void ficlCompileGfx(FICL_SYSTEM *pSys)
+{
+    ficlCompileFcn **fnpp;
+    FICL_DICT *dp = pSys->dp;
+    assert (dp);
+
+    dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT);
+    dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT);
+    dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT);
+    dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT);
+    dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT);
+    dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT);
+    dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT);
+
+    return;
+}
+FICL_COMPILE_SET(ficlCompileGfx);
+
+void
+gfx_interp_md(void)
+{
+}
diff --git a/stand/ficl/loader.c b/stand/ficl/loader.c
index edde4f477d55..618d9483fbd9 100644
--- a/stand/ficl/loader.c
+++ b/stand/ficl/loader.c
@@ -44,8 +44,6 @@
 #include "bootstrap.h"
 #include <string.h>
 #include <uuid.h>
-#include <gfx_fb.h>
-#include <pnglite.h>
 #include "ficl.h"
 
 /*		FreeBSD's loader interaction words and extras
@@ -65,182 +63,6 @@
  * 		.#	    ( value -- )
  */
 
-#ifndef TESTMAIN
-/* ( flags x1 y1 x2 y2 -- flag ) */
-void
-ficl_term_putimage(FICL_VM *pVM)
-{
-        char *namep, *name;
-        int names;
-        unsigned long ret = FICL_FALSE;
-        uint32_t x1, y1, x2, y2, f;
-        png_t png;
-	int error;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 7, 1);
-#endif
-        names = stackPopINT(pVM->pStack);
-        namep = (char *) stackPopPtr(pVM->pStack);
-        y2 = stackPopINT(pVM->pStack);
-        x2 = stackPopINT(pVM->pStack);
-        y1 = stackPopINT(pVM->pStack);
-        x1 = stackPopINT(pVM->pStack);
-        f = stackPopINT(pVM->pStack);
-
-	x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width;
-	y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height;
-	if (x2 != 0) {
-		x2 = gfx_state.tg_origin.tp_col +
-		    x2 * gfx_state.tg_font.vf_width;
-	}
-	if (y2 != 0) {
-		y2 = gfx_state.tg_origin.tp_row +
-		    y2 * gfx_state.tg_font.vf_height;
-	}
-
-        name = ficlMalloc(names + 1);
-        if (!name)
-		vmThrowErr(pVM, "Error: out of memory");
-        (void) strncpy(name, namep, names);
-        name[names] = '\0';
-
-        if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
-		if (f & FL_PUTIMAGE_DEBUG)
-			printf("%s\n", png_error_string(error));
-	} else {
-                if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
-                        ret = FICL_TRUE;        /* success */
-                (void) png_close(&png);
-	}
-        ficlFree(name);
-	stackPushUNS(pVM->pStack, ret);
-}
-
-/* ( flags x1 y1 x2 y2 -- flag ) */
-void
-ficl_fb_putimage(FICL_VM *pVM)
-{
-        char *namep, *name;
-        int names;
-        unsigned long ret = FICL_FALSE;
-        uint32_t x1, y1, x2, y2, f;
-        png_t png;
-	int error;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 7, 1);
-#endif
-        names = stackPopINT(pVM->pStack);
-        namep = (char *) stackPopPtr(pVM->pStack);
-        y2 = stackPopINT(pVM->pStack);
-        x2 = stackPopINT(pVM->pStack);
-        y1 = stackPopINT(pVM->pStack);
-        x1 = stackPopINT(pVM->pStack);
-        f = stackPopINT(pVM->pStack);
-
-        name = ficlMalloc(names + 1);
-        if (!name)
-		vmThrowErr(pVM, "Error: out of memory");
-        (void) strncpy(name, namep, names);
-        name[names] = '\0';
-
-        if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
-		if (f & FL_PUTIMAGE_DEBUG)
-			printf("%s\n", png_error_string(error));
-	} else {
-                if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
-                        ret = FICL_TRUE;        /* success */
-                (void) png_close(&png);
-	}
-        ficlFree(name);
-	stackPushUNS(pVM->pStack, ret);
-}
-
-void
-ficl_fb_setpixel(FICL_VM *pVM)
-{
-        FICL_UNS x, y;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 2, 0);
-#endif
-
-        y = stackPopUNS(pVM->pStack);
-        x = stackPopUNS(pVM->pStack);
-        gfx_fb_setpixel(x, y);
-}
-
-void
-ficl_fb_line(FICL_VM *pVM)
-{
-	FICL_UNS x0, y0, x1, y1, wd;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 5, 0);
-#endif
-
-	wd = stackPopUNS(pVM->pStack);
-	y1 = stackPopUNS(pVM->pStack);
-	x1 = stackPopUNS(pVM->pStack);
-	y0 = stackPopUNS(pVM->pStack);
-	x0 = stackPopUNS(pVM->pStack);
-	gfx_fb_line(x0, y0, x1, y1, wd);
-}
-
-void
-ficl_fb_bezier(FICL_VM *pVM)
-{
-	FICL_UNS x0, y0, x1, y1, x2, y2, width;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 7, 0);
-#endif
-
-	width = stackPopUNS(pVM->pStack);
-	y2 = stackPopUNS(pVM->pStack);
-	x2 = stackPopUNS(pVM->pStack);
-	y1 = stackPopUNS(pVM->pStack);
-	x1 = stackPopUNS(pVM->pStack);
-	y0 = stackPopUNS(pVM->pStack);
-	x0 = stackPopUNS(pVM->pStack);
-	gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width);
-}
-
-void
-ficl_fb_drawrect(FICL_VM *pVM)
-{
-	FICL_UNS x1, x2, y1, y2, fill;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 5, 0);
-#endif
-
-	fill = stackPopUNS(pVM->pStack);
-	y2 = stackPopUNS(pVM->pStack);
-	x2 = stackPopUNS(pVM->pStack);
-	y1 = stackPopUNS(pVM->pStack);
-	x1 = stackPopUNS(pVM->pStack);
-	gfx_fb_drawrect(x1, y1, x2, y2, fill);
-}
-
-void
-ficl_term_drawrect(FICL_VM *pVM)
-{
-	FICL_UNS x1, x2, y1, y2;
-
-#if FICL_ROBUST > 1
-	vmCheckStack(pVM, 4, 0);
-#endif
-
-	y2 = stackPopUNS(pVM->pStack);
-	x2 = stackPopUNS(pVM->pStack);
-	y1 = stackPopUNS(pVM->pStack);
-	x1 = stackPopUNS(pVM->pStack);
-	gfx_term_drawrect(x1, y1, x2, y2);
-}
-#endif	/* TESTMAIN */
-
 void
 ficlSetenv(FICL_VM *pVM)
 {
@@ -1042,16 +864,6 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys)
     dictAppendWord(dp, "ccall",	    ficlCcall,	    FW_DEFAULT);
     dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT);
     dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT);
-#ifndef TESTMAIN
-    dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT);
-    dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT);
-    dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT);
-    dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT);
-    dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT);
-    dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT);
-    dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT);
-    dictAppendWord(dp, "isvirtualized?",ficlIsvirtualizedQ, FW_DEFAULT);
-#endif
     
     SET_FOREACH(fnpp, Xficl_compile_set)
 	(*fnpp)(pSys);