public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] libgccjit: Add new gcc_jit_context_new_blob entry point
@ 2020-06-03 10:11 Andrea Corallo
  2020-06-03 15:03 ` David Malcolm
  0 siblings, 1 reply; 14+ messages in thread
From: Andrea Corallo @ 2020-06-03 10:11 UTC (permalink / raw)
  To: gcc-patches, jit; +Cc: nd, David Malcolm

[-- Attachment #1: Type: text/plain, Size: 2474 bytes --]

Hi all,

I'd like to submit this patch to extend libgccjit to allow for storing
binary blobs (equivalent to initialized char arrays).

The use-case is when libgccjit is used as a back-end for dynamic
programming languages.  In this case is often necessary to store
serialized objects into the compilation unit as support to the
generated code.

The proposed entry point is the following:

gcc_jit_lvalue *
gcc_jit_context_new_blob (gcc_jit_context *ctxt,
			  gcc_jit_location *loc,
			  enum gcc_jit_global_kind kind,
			  const void *ptr,
			  size_t size,
			  const char *name);

This create a special kind of libgccjit global that will be initialized
with the memory content pointed by 'ptr'.

I've added a testcase and the regression is clean.  I've also tested
it with the libgccjit based Emacs disabling the current workaround we have
for this.

Feedback is very welcome.

  Andrea

gcc/jit/ChangeLog

2020-06-02  Andrea Corallo  <andrea.corallo@arm.com>

	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_14): New ABI tag.

	* docs/topics/expressions.rst (Binary Blobs): New section
	documenting gcc_jit_context_new_blob.

	* jit-common.h: Document class blob.

	* jit-playback.c (playback::context::global_new_decl)
	(playback::context::global_finalize_lvalue): New methods.
	(playback::context::new_global): Make use of global_new_decl,
	global_finalize_lvalue.
	(playback::context::new_blob): New method.

	* jit-playback.h (new_blob, global_new_decl): New method
	declarations.

	* jit-recording.c (recording::context::new_blob)
	(recording::blob::replay_into)
	(recording::global::write_qualifier_to_dump): New methods.
	(recording::global::write_to_dump): Use write_qualifier_to_dump.
	(recording::blob::write_to_dump): New method.

	* jit-recording.h (class blob): New class.
	(class global): Have m_kind and m_name as protected.
	(class global): Remove FINAL qualifier to replay_into and
	write_to_dump.
	(class global): New method write_qualifier_to_dump decl.
	(class context): New method new_blob decl.

	* libgccjit++.h (context::new_blob): New method.

	* libgccjit.c (gcc_jit_lvalue_as_rvalue): New function.

	* libgccjit.h (gcc_jit_context_new_blob): New function
	declaration.
	(LIBGCCJIT_HAVE_gcc_jit_context_new_blob): New macro.

	* libgccjit.map (LIBGCCJIT_ABI_14): New ABI tag.

gcc/testsuite/ChangeLog

2020-06-02  Andrea Corallo  <andrea.corallo@arm.com>

	* jit.dg/all-non-failing-tests.h: Add test-blob.c.

	* jit.dg/test-blob.c: New test.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-new-gcc_jit_context_new_blob-entry-point.patch --]
[-- Type: text/x-diff, Size: 20317 bytes --]

From b861fbbfbcbf18cc1b69dc4b7f91c596af40c8e4 Mon Sep 17 00:00:00 2001
From: Andrea Corallo <andrea.corallo@arm.com>
Date: Sat, 30 May 2020 10:33:08 +0100
Subject: [PATCH] Add new gcc_jit_context_new_blob entry point

gcc/jit/ChangeLog

2020-06-02  Andrea Corallo  <andrea.corallo@arm.com>

	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_14): New ABI tag.

	* docs/topics/expressions.rst (Binary Blobs): New section
	documenting gcc_jit_context_new_blob.

	* jit-common.h: Document class blob.

	* jit-playback.c (playback::context::global_new_decl)
	(playback::context::global_finalize_lvalue): New methods.
	(playback::context::new_global): Make use of global_new_decl,
	global_finalize_lvalue.
	(playback::context::new_blob): New method.

	* jit-playback.h (new_blob, global_new_decl): New method
	declarations.

	* jit-recording.c (recording::context::new_blob)
	(recording::blob::replay_into)
	(recording::global::write_qualifier_to_dump): New methods.
	(recording::global::write_to_dump): Use write_qualifier_to_dump.
	(recording::blob::write_to_dump): New method.

	* jit-recording.h (class blob): New class.
	(class global): Have m_kind and m_name as protected.
	(class global): Remove FINAL qualifier to replay_into and
	write_to_dump.
	(class global): New method write_qualifier_to_dump decl.
	(class context): New method new_blob decl.

	* libgccjit++.h (context::new_blob): New method.

	* libgccjit.c (gcc_jit_lvalue_as_rvalue): New function.

	* libgccjit.h (gcc_jit_context_new_blob): New function
	declaration.
	(LIBGCCJIT_HAVE_gcc_jit_context_new_blob): New macro.

	* libgccjit.map (LIBGCCJIT_ABI_14): New ABI tag.

gcc/testsuite/ChangeLog

2020-06-02  Andrea Corallo  <andrea.corallo@arm.com>

	* jit.dg/all-non-failing-tests.h: Add test-blob.c.

	* jit.dg/test-blob.c: New test.
---
 gcc/jit/docs/topics/compatibility.rst        |  5 ++
 gcc/jit/docs/topics/expressions.rst          | 49 ++++++++++
 gcc/jit/jit-common.h                         |  1 +
 gcc/jit/jit-playback.c                       | 67 ++++++++++++--
 gcc/jit/jit-playback.h                       | 16 ++++
 gcc/jit/jit-recording.c                      | 95 +++++++++++++++++---
 gcc/jit/jit-recording.h                      | 48 +++++++++-
 gcc/jit/libgccjit++.h                        | 21 +++++
 gcc/jit/libgccjit.c                          | 30 +++++++
 gcc/jit/libgccjit.h                          | 17 ++++
 gcc/jit/libgccjit.map                        |  7 +-
 gcc/testsuite/jit.dg/all-non-failing-tests.h |  7 ++
 gcc/testsuite/jit.dg/test-blob.c             | 54 +++++++++++
 13 files changed, 393 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-blob.c

diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 0c0ce070d722..3d9684c73b4b 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -215,3 +215,8 @@ entrypoints:
   * :func:`gcc_jit_version_minor`
 
   * :func:`gcc_jit_version_patchlevel`
+
+``LIBGCCJIT_ABI_14``
+--------------------
+``LIBGCCJIT_ABI_14`` covers the addition of
+:func:`gcc_jit_context_new_blob`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index db2f2ca2e9c6..deb46594d80a 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -576,6 +576,55 @@ Global variables
       referring to it.  Analogous to using an "extern" global from a
       header file.
 
+Binary Blobs
+****************
+
+.. function:: gcc_jit_context_new_blob (gcc_jit_context *ctxt,\
+                                        gcc_jit_location *loc,\
+                                        enum gcc_jit_global_kind kind,\
+                                        const void *ptr,\
+                                        size_t size,\
+                                        const char *name);
+
+   Add a new global variable equivalent to an initialized array of
+   char to the context.
+
+   The parameter ``name`` must be non-NULL.  The call takes a copy of the
+   underlying string, so it is valid to pass in a pointer to an on-stack
+   buffer.
+
+   Similarly the parameter ``ptr`` must be non-NULL. The call copies
+   the memory content pointed by ``ptr`` for ``size`` bytes.  This
+   content will be stores in the compilation unit and used as
+   initialization value of the array.
+
+   .. c:macro:: GCC_JIT_GLOBAL_EXPORTED
+
+      Global is defined by the client code and is visible
+      by name outside of this JIT context via
+      :c:func:`gcc_jit_result_get_global` (and this value is required for
+      the global to be accessible via that entrypoint).
+
+   .. c:macro:: GCC_JIT_GLOBAL_INTERNAL
+
+      Global is defined by the client code, but is invisible
+      outside of it.  Analogous to a "static" global within a .c file.
+      Specifically, the variable will only be visible within this
+      context and within child contexts.
+
+   .. c:macro:: GCC_JIT_GLOBAL_IMPORTED
+
+      Global is not defined by the client code; we're merely
+      referring to it.  Analogous to using an "extern" global from a
+      header file.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_14`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_blob
+
 Working with pointers, structs and unions
 -----------------------------------------
 
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 4570bd2d717f..7a1578d10e89 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -127,6 +127,7 @@ namespace recording {
       class lvalue;
         class local;
 	class global;
+  	  class blob;
         class param;
       class base_call;
       class function_pointer;
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 074434a9f6b2..1cc674a8ddd9 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -111,6 +111,14 @@ public:
 	      type *type,
 	      const char *name);
 
+  lvalue *
+  new_blob (location *loc,
+            enum gcc_jit_global_kind kind,
+            type *type,
+            const void *ptr,
+            size_t size,
+            const char *name);
+
   template <typename HOST_TYPE>
   rvalue *
   new_rvalue_from_const (type *type,
@@ -266,6 +274,14 @@ private:
   const char * get_path_s_file () const;
   const char * get_path_so_file () const;
 
+  tree
+  global_new_decl (location *loc,
+                   enum gcc_jit_global_kind kind,
+                   type *type,
+                   const char *name);
+  lvalue *
+  global_finalize_lvalue (tree inner);
+
 private:
 
   /* Functions for implementing "compile".  */
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index d2c8bb4c154d..8cd986942bc7 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -506,14 +506,14 @@ new_function (location *loc,
   return func;
 }
 
-/* Construct a playback::lvalue instance (wrapping a tree).  */
+/* In use by new_global and new_blob.  */
 
-playback::lvalue *
+tree
 playback::context::
-new_global (location *loc,
-	    enum gcc_jit_global_kind kind,
-	    type *type,
-	    const char *name)
+global_new_decl (location *loc,
+		 enum gcc_jit_global_kind kind,
+		 type *type,
+		 const char *name)
 {
   gcc_assert (type);
   gcc_assert (name);
@@ -543,6 +543,15 @@ new_global (location *loc,
   if (loc)
     set_tree_location (inner, loc);
 
+  return inner;
+}
+
+/* In use by new_global and new_blob.  */
+
+playback::lvalue *
+playback::context::
+global_finalize_lvalue (tree inner)
+{
   varpool_node::get_create (inner);
 
   varpool_node::finalize_decl (inner);
@@ -552,6 +561,52 @@ new_global (location *loc,
   return new lvalue (this, inner);
 }
 
+/* Construct a playback::lvalue instance (wrapping a tree).  */
+
+playback::lvalue *
+playback::context::
+new_global (location *loc,
+	    enum gcc_jit_global_kind kind,
+	    type *type,
+	    const char *name)
+{
+  tree inner = global_new_decl (loc, kind, type, name);
+
+  return global_finalize_lvalue (inner);
+}
+
+playback::lvalue *
+playback::context::
+new_blob (location *loc,
+	  enum gcc_jit_global_kind kind,
+	  type *type,
+	  const void *ptr,
+	  size_t size,
+	  const char *name)
+{
+  tree inner = global_new_decl (loc, kind, type, name);
+
+  static vec<constructor_elt, va_gc> *constructor_elements;
+  const char *p = (const char *)ptr;
+  for (size_t i = 0; i < size; i++)
+    {
+      /* Compare with 'output_init_element' c-typeck.c:9691.  */
+      constructor_elt celt =
+	{ build_int_cst (long_unsigned_type_node, i),
+	  build_int_cst (char_type_node, p[i]) };
+      vec_safe_push (constructor_elements, celt);
+    }
+  /* Compare with 'pop_init_level' c-typeck.c:8780.  */
+  tree ctor = build_constructor (type->as_tree (), constructor_elements);
+  constructor_elements = NULL;
+
+  /* Compare with 'store_init_value' c-typeck.c:7555.  */
+  DECL_INITIAL (inner) = ctor;
+
+  return global_finalize_lvalue (inner);
+}
+
+
 /* Implementation of the various
       gcc::jit::playback::context::new_rvalue_from_const <HOST_TYPE>
    methods.
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 726b9c4b8371..5e2762ff8785 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -204,6 +204,13 @@ public:
 	    rvalue *max_value,
 	    block *block);
 
+  lvalue *
+  new_blob (location *loc,
+            enum gcc_jit_global_kind kind,
+            const void *ptr,
+            size_t size,
+            const char *name);
+
   void
   set_str_option (enum gcc_jit_str_option opt,
 		  const char *value);
@@ -1329,11 +1336,14 @@ public:
     m_name (name)
   {}
 
-  void replay_into (replayer *) FINAL OVERRIDE;
+  void replay_into (replayer *) OVERRIDE;
 
   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
 
-  void write_to_dump (dump &d) FINAL OVERRIDE;
+  void write_to_dump (dump &d) OVERRIDE;
+
+protected:
+  void write_qualifier_to_dump (dump &d);
 
 private:
   string * make_debug_string () FINAL OVERRIDE { return m_name; }
@@ -1343,11 +1353,43 @@ private:
     return PRECEDENCE_PRIMARY;
   }
 
-private:
+protected:
   enum gcc_jit_global_kind m_kind;
   string *m_name;
 };
 
+class blob : public global
+{
+public:
+  blob (context *ctxt,
+        location *loc,
+        enum gcc_jit_global_kind kind,
+        void *ptr,
+        size_t size,
+        string *name)
+    : global (ctxt, loc, kind,
+              ctxt->new_array_type (loc,
+                                    ctxt->get_type (GCC_JIT_TYPE_CHAR),
+                                    size),
+              name),
+      m_ptr (ptr),
+      m_size (size)
+  {}
+
+  ~blob ()
+  {
+    free (m_ptr);
+  }
+
+  void replay_into (replayer *) FINAL OVERRIDE;
+
+  void write_to_dump (dump &d) FINAL OVERRIDE;
+
+private:
+  void *m_ptr;
+  size_t m_size;
+};
+
 template <typename HOST_TYPE>
 class memento_of_new_rvalue_from_const : public rvalue
 {
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index b73cd76a0a02..b23ebdc57d2c 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -1229,6 +1229,29 @@ recording::context::new_case (recording::rvalue *min_value,
   return result;
 }
 
+/* Create a recording::blob instance and add it to this context's list
+   of mementos.
+
+   Implements the post-error-checking part of
+   gcc_jit_context_new_blob.  */
+
+recording::lvalue *
+recording::context::new_blob (recording::location *loc,
+			      enum gcc_jit_global_kind kind,
+			      const void *ptr,
+			      size_t size,
+			      const char *name)
+{
+  void *data = xmalloc (size);
+  recording::blob *result =
+    new recording::blob (this, loc, kind, memcpy (data, ptr, size), size,
+			 new_string (name));
+  record (result);
+  m_globals.safe_push (result);
+
+  return result;
+}
+
 /* Set the given string option for this context, or add an error if
    it's not recognized.
 
@@ -4399,6 +4422,38 @@ recording::global::replay_into (replayer *r)
 				   playback_string (m_name)));
 }
 
+void
+recording::blob::replay_into (replayer *r)
+{
+  set_playback_obj (r->new_blob (playback_location (r, m_loc),
+				 m_kind,
+				 m_type->playback_type (),
+				 m_ptr,
+				 m_size,
+				 playback_string (m_name)));
+}
+
+void
+recording::global::write_qualifier_to_dump (dump &d)
+{
+  switch (m_kind)
+    {
+    default:
+      gcc_unreachable ();
+
+    case GCC_JIT_GLOBAL_EXPORTED:
+      break;
+
+    case GCC_JIT_GLOBAL_INTERNAL:
+      d.write ("static ");
+      break;
+
+    case GCC_JIT_GLOBAL_IMPORTED:
+      d.write ("extern ");
+      break;
+    }
+}
+
 /* Override the default implementation of
    recording::memento::write_to_dump for globals.
    This will be of the form:
@@ -4424,25 +4479,37 @@ recording::global::write_to_dump (dump &d)
   if (d.update_locations ())
     m_loc = d.make_location ();
 
-  switch (m_kind)
-    {
-    default:
-      gcc_unreachable ();
+  write_qualifier_to_dump (d);
 
-    case GCC_JIT_GLOBAL_EXPORTED:
-      break;
+  d.write ("%s %s;\n",
+	   m_type->get_debug_string (),
+	   get_debug_string ());
+}
 
-    case GCC_JIT_GLOBAL_INTERNAL:
-      d.write ("static ");
-      break;
 
-    case GCC_JIT_GLOBAL_IMPORTED:
-      d.write ("extern ");
-      break;
-    }
-  d.write ("%s %s;\n",
+/* Override the default implementation of
+   recording::memento::write_to_dump for blobs.  */
+
+void
+recording::blob::write_to_dump (dump &d)
+{
+  if (d.update_locations ())
+    m_loc = d.make_location ();
+
+  write_qualifier_to_dump (d);
+
+  d.write ("%s %s =\n  { ",
 	   m_type->get_debug_string (),
 	   get_debug_string ());
+
+  const char *p = (const char *)m_ptr;
+  for (size_t i = 0; i < m_size; i++)
+    {
+      d.write ("0x%x, ", p[i]);
+      if (i && !(i % 64))
+	d.write ("\n    ");
+    }
+  d.write ("};\n");
 }
 
 /* A table of enum gcc_jit_global_kind values expressed in string
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 69e67766640c..bb663e9aca1f 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -182,6 +182,12 @@ namespace gccjit
 		       const std::string &name,
 		       location loc = location ());
 
+    lvalue new_blob (enum gcc_jit_global_kind kind,
+                     const void *ptr,
+                     size_t size,
+                     const std::string &name,
+                     location loc = location ());
+
     rvalue new_rvalue (type numeric_type,
 		       int value) const;
     rvalue new_rvalue (type numeric_type,
@@ -860,6 +866,21 @@ context::new_global (enum gcc_jit_global_kind kind,
 					     name.c_str ()));
 }
 
+inline lvalue
+context::new_blob (enum gcc_jit_global_kind kind,
+                   const void *ptr,
+                   size_t size,
+                   const std::string &name,
+                   location loc)
+{
+  return lvalue (gcc_jit_context_new_blob (m_inner_ctxt,
+                                           loc.get_inner_location (),
+                                           kind,
+                                           ptr,
+					   size,
+                                           name.c_str ()));
+}
+
 inline rvalue
 context::new_rvalue (type numeric_type,
 		     int value) const
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 1c5a12e9c015..a66be3568fa0 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -788,6 +788,23 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
 			    gcc_jit_type *type,
 			    const char *name);
 
+#define LIBGCCJIT_HAVE_gcc_jit_context_new_blob
+
+/* Create a binary blob.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_14; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_blob
+*/
+
+extern gcc_jit_lvalue *
+gcc_jit_context_new_blob (gcc_jit_context *ctxt,
+			  gcc_jit_location *loc,
+			  enum gcc_jit_global_kind kind,
+			  const void *ptr,
+			  size_t size,
+			  const char *name);
+
 /* Upcasting.  */
 extern gcc_jit_object *
 gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue);
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index a29e9885e59b..a504d568b388 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -1097,6 +1097,36 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
   return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::context::new_blob method, in
+   jit-recording.c.  */
+
+gcc_jit_lvalue *
+gcc_jit_context_new_blob (gcc_jit_context *ctxt,
+			  gcc_jit_location *loc,
+			  enum gcc_jit_global_kind kind,
+			  const void *ptr,
+			  size_t size,
+			  const char *name)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  /* LOC can be NULL.  */
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    ((kind >= GCC_JIT_GLOBAL_EXPORTED)
+     && (kind <= GCC_JIT_GLOBAL_IMPORTED)),
+    ctxt, loc,
+    "unrecognized value for enum gcc_jit_global_kind: %i",
+    kind);
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL ptr");
+  /* SIZE can be zero.  */
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
+
+  return (gcc_jit_lvalue *)ctxt->new_blob (loc, kind, ptr, size, name);
+}
+
 /* Public entrypoint.  See description in libgccjit.h.
 
    After error-checking, this calls the trivial
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 6137dd4b4b03..40c3605310d8 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -186,4 +186,9 @@ LIBGCCJIT_ABI_13 {
     gcc_jit_version_major;
     gcc_jit_version_minor;
     gcc_jit_version_patchlevel;
-} LIBGCCJIT_ABI_12;
\ No newline at end of file
+} LIBGCCJIT_ABI_12;
+
+LIBGCCJIT_ABI_14 {
+  global:
+    gcc_jit_context_new_blob;
+} LIBGCCJIT_ABI_13;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index ad469dad6994..7eaf373e6ed8 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -67,6 +67,13 @@
 #undef create_code
 #undef verify_code
 
+/* test-blob.c */
+#define create_code create_code_blob
+#define verify_code verify_code_blob
+#include "test-blob.c"
+#undef create_code
+#undef verify_code
+
 /* test-calling-external-function.c */
 #define create_code create_code_calling_external_function
 #define verify_code verify_code_calling_external_function
diff --git a/gcc/testsuite/jit.dg/test-blob.c b/gcc/testsuite/jit.dg/test-blob.c
new file mode 100644
index 000000000000..d344975dd5a7
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-blob.c
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#define BIG_BLOB_SIZE (1 << 12) /* 4KB.  */
+
+static char test_blob1[] = { 0xc, 0xa, 0xf, 0xf, 0xe };
+static char test_blob2[] = { 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3 };
+static char test_blob3[BIG_BLOB_SIZE];
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+
+     char bin_blob1[] = { 0xc, 0xa, 0xf, 0xf, 0xe };
+     char bin_blob2[] = { 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3 };
+     char bin_blob3[4096]...
+  */
+
+  gcc_jit_context_new_blob (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, test_blob1,
+			    sizeof (test_blob1), "bin_blob1");
+
+  gcc_jit_context_new_blob (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, test_blob2,
+			    sizeof (test_blob2), "bin_blob2");
+
+  for (size_t i = 0; i < BIG_BLOB_SIZE; i++)
+    test_blob3[i] = i * i + i;
+  gcc_jit_context_new_blob (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, test_blob3,
+			    sizeof (test_blob3), "bin_blob3");
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+  void *blob = gcc_jit_result_get_global (result, "bin_blob1");
+  CHECK_NON_NULL (blob);
+  CHECK_VALUE (memcmp (test_blob1, blob, sizeof (test_blob1)), 0);
+
+  blob = gcc_jit_result_get_global (result, "bin_blob2");
+  CHECK_NON_NULL (blob);
+  CHECK_VALUE (memcmp (test_blob2, blob, sizeof (test_blob2)), 0);
+
+  blob = gcc_jit_result_get_global (result, "bin_blob3");
+  CHECK_NON_NULL (blob);
+  CHECK_VALUE (memcmp (test_blob3, blob, sizeof (test_blob3)), 0);
+
+}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-09-11 11:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-03 10:11 [PATCH] libgccjit: Add new gcc_jit_context_new_blob entry point Andrea Corallo
2020-06-03 15:03 ` David Malcolm
2020-06-03 16:36   ` Andrea Corallo
2020-07-01 16:14     ` Andrea Corallo
2020-07-14 10:00       ` Andrea Corallo
2020-07-24 22:05       ` David Malcolm
2020-07-24 22:12         ` David Malcolm
2020-08-03  8:07           ` Andrea Corallo
2020-08-06 19:53             ` David Malcolm
2020-08-19  7:17               ` [PATCH V2] " Andrea Corallo
2020-09-09  7:51                 ` Andrea Corallo
2020-09-10 22:22                 ` David Malcolm
2020-09-11 10:31                   ` Andrea Corallo
2020-09-11 11:27                     ` David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).