From patchwork Mon Mar 10 18:41:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 328697 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 783432C0081 for ; Tue, 11 Mar 2014 05:43:35 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=ijUGydcVPR/Z q3K+2d59N4PfnNGEgOoAfz76LMIghTr0pJ8i+EVB6EwQkFlnaQUeAQZuHBVDOUlj t0+PVy73tVce9WdCEbur3ypluLaMQ7gAttyLVKAOGWwtV8t+lwjPfESWNxxvX+d9 yTicknWOMY8hQDQIO0Iw2H9LfMD+ZKo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=kCFXG5+dVGZsovriD4 +rYRCB+A4=; b=WLKB/xS0FFF04gt5ciHzljrkKdMbWa7g1GIJi1pOpKWIN0l89e WdojxLPqvjFUaA2d977G5++pMoQirpoEgDHEp8SynpQmokaa5+PDgpktssvl4woE UhDcvHSgvfPF7Kl7GdS0xI2A+9uw+zwgSG2YSu21eAT6uH5ZY/W4gEidU= Received: (qmail 28828 invoked by alias); 10 Mar 2014 18:43:27 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 28805 invoked by uid 89); 10 Mar 2014 18:43:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 10 Mar 2014 18:43:23 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2AIhLOV016173 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 10 Mar 2014 14:43:22 -0400 Received: from surprise.redhat.com (vpn-239-141.phx2.redhat.com [10.3.239.141]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s2AIhLCa008472; Mon, 10 Mar 2014 14:43:21 -0400 From: David Malcolm To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [jit] Use exceptions in the C++ wrapper API Date: Mon, 10 Mar 2014 14:41:44 -0400 Message-Id: <1394476904-25460-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes 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(-) 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 + + * 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 * 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)) {}