Patchwork [jit] Use exceptions in the C++ wrapper API

login
register
mail settings
Submitter David Malcolm
Date March 10, 2014, 6:41 p.m.
Message ID <1394476904-25460-1-git-send-email-dmalcolm@redhat.com>
Download mbox | patch
Permalink /patch/328697/
State New
Headers show

Comments

David Malcolm - March 10, 2014, 6:41 p.m.
Committed to branch dmalcolm/jit:

Error-handling in the C API works by returning NULL when an error
occurs (and setting an error on the context), and handling NULL inputs
by immediately returning NULL (setting another error).  Hence the
presence of a NULL indicates some kind of error has occurred.

Update the C++ API to check for NULL pointers in the constructors for
the various wrappers classes, throwing an exception if one if passed in.

Hence any erroneous use of the API (e.g. type-mismatches) will lead to
immediate failure, rather than the previous behavior of a flurry of
text on stderr.

Also, make gccjit::context::m_inner private.

gcc/jit/
	* libgccjit++.h (gccjit::error): New class, for exceptions.
	(gccjit::context::get_inner_context): New accessor, so that we
	can...
	(gccjit::context::m_inner_ctxt): Make private.
	(gccjit::context::context): Throw a gccjit::error if a NULL
	context is passed in.
	(gccjit::context::compile): Throw a gccjit::error if a NULL
	result is returned from the C API, which indicates an error.
	(gccjit::object::object): Throw a gccjit::error if a NULL
	object is passed in, since that indicates that an error has
	occurred.
	(gccjit::location::location): In the default ctor, call the
	base class default ctor rather than passing in a NULL to the
	single-argument ctor, since the latter now indicates an error
	has occurred at the C API level.
	(gccjit::field::field): Likewise.
	(gccjit::type::type): Likewise.
	(gccjit::function::function): Likewise.
	(gccjit::block::block): Likewise.
	(gccjit::rvalue::rvalue): Likewise.
---
 gcc/jit/ChangeLog.jit | 23 +++++++++++++++++++++++
 gcc/jit/libgccjit++.h | 38 ++++++++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 10 deletions(-)

Patch

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 223fd6a..fcb0244 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,26 @@ 
+2014-03-10  David Malcolm  <dmalcolm@redhat.com>
+
+	* libgccjit++.h (gccjit::error): New class, for exceptions.
+	(gccjit::context::get_inner_context): New accessor, so that we
+	can...
+	(gccjit::context::m_inner_ctxt): Make private.
+	(gccjit::context::context): Throw a gccjit::error if a NULL
+	context is passed in.
+	(gccjit::context::compile): Throw a gccjit::error if a NULL
+	result is returned from the C API, which indicates an error.
+	(gccjit::object::object): Throw a gccjit::error if a NULL
+	object is passed in, since that indicates that an error has
+	occurred.
+	(gccjit::location::location): In the default ctor, call the
+	base class default ctor rather than passing in a NULL to the
+	single-argument ctor, since the latter now indicates an error
+	has occurred at the C API level.
+	(gccjit::field::field): Likewise.
+	(gccjit::type::type): Likewise.
+	(gccjit::function::function): Likewise.
+	(gccjit::block::block): Likewise.
+	(gccjit::rvalue::rvalue): Likewise.
+
 2014-03-07  David Malcolm  <dmalcolm@redhat.com>
 
 	* libgccjit.h (enum gcc_jit_function_kind): Add
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 71bb855..cd02dde 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -26,6 +26,11 @@  namespace gccjit
   class rvalue;
   class lvalue;
 
+  /* Errors within the API become C++ exceptions of this class.  */
+  class error
+  {
+  };
+
   class object
   {
   public:
@@ -68,6 +73,8 @@  namespace gccjit
 
     gccjit::context new_child_context ();
 
+    gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
+
     void release ();
 
     gcc_jit_result *compile ();
@@ -251,7 +258,7 @@  namespace gccjit
 			     rvalue index,
 			     location loc = location ());
 
-  public:
+  private:
     gcc_jit_context *m_inner_ctxt;
   };
 
@@ -473,7 +480,11 @@  inline context context::acquire ()
   return context (gcc_jit_context_acquire ());
 }
 inline context::context () : m_inner_ctxt (NULL) {}
-inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner) {}
+inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
+{
+  if (!inner)
+    throw error ();
+}
 
 inline gccjit::context
 context::new_child_context ()
@@ -491,7 +502,10 @@  context::release ()
 inline gcc_jit_result *
 context::compile ()
 {
-  return gcc_jit_context_compile (m_inner_ctxt);
+  gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
+  if (!result)
+    throw error ();
+  return result;
 }
 
 inline void
@@ -1026,7 +1040,11 @@  object::get_debug_string () const
 }
 
 inline object::object () : m_inner_obj (NULL) {}
-inline object::object (gcc_jit_object *obj) : m_inner_obj (obj) {}
+inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
+{
+  if (!obj)
+    throw error ();
+}
 
 inline gcc_jit_object *
 object::get_inner_object () const
@@ -1041,7 +1059,7 @@  operator << (std::ostream& stream, const object &obj)
 }
 
 // class location
-inline location::location () : object (NULL) {}
+inline location::location () : object () {}
 inline location::location (gcc_jit_location *loc)
   : object (gcc_jit_location_as_object (loc))
 {}
@@ -1054,7 +1072,7 @@  location::get_inner_location () const
 }
 
 // class field
-inline field::field () : object (NULL) {}
+inline field::field () : object () {}
 inline field::field (gcc_jit_field *inner)
   : object (gcc_jit_field_as_object (inner))
 {}
@@ -1067,7 +1085,7 @@  field::get_inner_field () const
 }
 
 // class type
-inline type::type () : object (NULL) {}
+inline type::type () : object () {}
 inline type::type (gcc_jit_type *inner)
   : object (gcc_jit_type_as_object (inner))
 {}
@@ -1118,7 +1136,7 @@  struct_::get_inner_struct () const
 }
 
 // class function
-inline function::function () : object (NULL) {}
+inline function::function () : object () {}
 inline function::function (gcc_jit_function *inner)
   : object (gcc_jit_function_as_object (inner))
 {}
@@ -1332,7 +1350,7 @@  function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
 }
 
 // class block
-inline block::block () : object (NULL) {}
+inline block::block () : object () {}
 inline block::block (gcc_jit_block *inner)
   : object (gcc_jit_block_as_object (inner))
 {}
@@ -1345,7 +1363,7 @@  block::get_inner_block () const
 }
 
 //  class rvalue
-inline rvalue::rvalue () : object (NULL) {}
+inline rvalue::rvalue () : object () {}
 inline rvalue::rvalue (gcc_jit_rvalue *inner)
   : object (gcc_jit_rvalue_as_object (inner))
 {}