def bsort_expr(n, datatype): def assign(var, val): return ir.Stmt((ir.assignment, var, val)) def item(name): return ir.Struct_item(ir.Primitive_type(datatype), (name)) t = ir.Struct(ir.Scoped_id([("s")], ('Vector'), ''), [item('m%d'%i) for i in range(1, n+1)], '') a = ir.Arg([], ir.in_, t, 'a') b = ir.Arg([], ir.inout, t, 'b') copy = [ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "a"), item('m%d'%i)))) for i in range(1, n+1)] sort = [(ir.var_decl, ir.pt_bool, ("swapped")), (ir.var_decl, ir.pt_int, ("tmp")), (ir.do_while, ("swapped"), # if A[i-1] > A[i] [assign(("swapped"), ir.Bool(ir.false))]+ [[(ir.if_, (ir.Infix_expr(ir.gt, ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1))), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%i)))), # swap( A[i-1], A[i] ) # swapped = true [assign(("tmp"), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%i))), ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%i), ir.Get_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1))))), ir.Stmt(ir.Set_struct_item(t, (ir.deref, "b"), item('m%d'%(i-1)), ("tmp"))), assign(("swapped"), ir.Bool(ir.true))])] for i in range(2, n+1)])] return copy+sort+[ir.Stmt(ir.Return(retval(n, datatype)))]
def static_ior_args(args, symbol_table, class_name): """ \return a SIDL -> Ir lowered version of [self]+args+(sidl_BaseInterface__object*)[*ex] """ arg_self = [ ir.Arg([], ir.in_, ir_object_type(symbol_table.prefix, class_name), 'self') ] arg_ex = [ir.Arg([], sidlir.out, ir_baseinterface_type(), '_ex')] return arg_self + lower_ir(symbol_table, args, qualify_names=True) + arg_ex
def stub_args(attrs, args, symbol_table, class_name, extra_attrs): """ \return a SIDL -> [*self]+args+[*ex] """ if member_chk(sidlir.static, attrs): arg_self = [] else: arg_self = [ ir.Arg(extra_attrs, sidlir.in_, ir_object_type(symbol_table.prefix, class_name), 'self') ] arg_ex = \ [ir.Arg(extra_attrs, sidlir.out, ir_exception_type(), '_ex')] return arg_self + args + arg_ex
def epv_args(attrs, args, symbol_table, class_name): """ \return a SIDL -> Ir lowered version of [self]+args+[*ex] """ if member_chk(sidlir.static, attrs): arg_self = [] else: arg_self = \ [ir.Arg([], ir.in_, ir_object_type(symbol_table.prefix, class_name), 'self')] arg_ex = \ [ir.Arg([], ir.out, ir_baseinterface_type(), '_ex')] return arg_self + lower_ir(symbol_table, args, qualify_names=True) + arg_ex
def vcall(name, args, ci): """ \return the IR for a non-static Babel virtual method call """ try: cdecl = ci.epv.find_method(name) epv_type = ci.epv.get_type() epv = ir.Get_struct_item(ci.obj, ir.Deref(args[0]), ir.Struct_item(epv_type, 'd_epv')) except: if False: # FIXME no_contracts and no_hooks: return ir.Call('_'.join(ci.co.qualified_name + [name]), args) else: cdecl = ci.epv.find_static_method(name) epv_type = ci.epv.get_sepv_type() epv = '_getSEPV()' # this is part of an ugly hack to make sure that self is # dereferenced as self->d_object (by setting attr of self to the # unused value of 'pure') if ci.co.is_interface() and args: _, attrs, type_, id_, arguments, doc = cdecl _, attrs0, mode0, type0, name0 = arguments[0] arguments = [ir.Arg([ir.pure], mode0, type0, name0)] + arguments[1:] cdecl = ir.Fn_decl(attrs, type_, id_, arguments, doc) return ir.Call( ir.Deref( ir.Get_struct_item( epv_type, ir.Deref(epv), ir.Struct_item(ir.Pointer_type(cdecl), 'f_' + name))), args)
def gen_default_methods(self, cls, has_contracts, ci): """ Generate default Babel object methods such as _cast() Also generates other IOR data structures such as the _object and the controls and statistics struct. """ def unscope((struct, scoped_id, items, doc)): return struct, c_gen(scoped_id), items, doc def builtin(t, name, args): ci.epv.add_method( sidlir.Method(t, sidlir.Method_name(name, ''), [], args, [], [], [], [], 'Implicit built-in method: '+name)) def static_builtin(t, name, args): ci.epv.add_method( sidlir.Method(t, sidlir.Method_name(name, ''), [sidlir.static], args, [], [], [], [], 'Implicit built-in method: '+name)) def inarg(t, name): return sidlir.Arg([], sidlir.in_, t, name) # Implicit Built-in methods builtin(sidlir.pt_opaque, '_cast', [inarg(sidlir.pt_string, 'name')]) builtin(sidlir.void, '_delete', []) builtin(sidlir.void, '_exec', [ inarg(sidlir.pt_string, 'methodName'), inarg(babel.object_type(['sidl', 'rmi'], 'Call'), 'inArgs'), inarg(babel.object_type(['sidl', 'rmi'], 'Return'), 'outArgs')]) builtin(sidlir.pt_string, '_getURL', []) builtin(sidlir.void, '_raddRef', []) builtin(sidlir.pt_bool, '_isRemote', []) builtin(sidlir.void, '_set_hooks', [inarg(sidlir.pt_bool, 'enable')]) builtin(sidlir.void, '_set_contracts', [ inarg(sidlir.pt_bool, 'enable'), inarg(sidlir.pt_string, 'enfFilename'), inarg(sidlir.pt_bool, 'resetCounters')], ) builtin(sidlir.void, '_dump_stats', [inarg(sidlir.pt_string, 'filename'), inarg(sidlir.pt_string, 'prefix')]) if not cls.is_interface(): builtin(sidlir.void, '_ctor', []) builtin(sidlir.void, '_ctor2', [(sidlir.arg, [], sidlir.in_, ir.void_ptr, 'private_data')]) builtin(sidlir.void, '_dtor', []) builtin(sidlir.void, '_load', []) static_builtin(sidlir.void, '_set_hooks_static', [inarg(sidlir.pt_bool, 'enable')]) static_builtin(sidlir.void, '_set_contracts_static', [ inarg(sidlir.pt_bool, 'enable'), inarg(sidlir.pt_string, 'enfFilename'), inarg(sidlir.pt_bool, 'resetCounters')], ) static_builtin(sidlir.void, '_dump_stats_static', [inarg(sidlir.pt_string, 'filename'), inarg(sidlir.pt_string, 'prefix')]) prefix = ci.epv.symbol_table.prefix # cstats cstats = [] contract_cstats = [] ci.methodcstats = [] num_methods = cls.number_of_methods() if has_contracts: ci.methodcstats = ir.Struct( ir.Scoped_id(prefix, ci.epv.name+'__method_cstats', ''), [ir.Struct_item(ir.Typedef_type('int32_t'), 'tries'), ir.Struct_item(ir.Typedef_type('int32_t'), 'successes'), ir.Struct_item(ir.Typedef_type('int32_t'), 'failures'), ir.Struct_item(ir.Typedef_type('int32_t'), 'nonvio_exceptions')], '') contract_cstats.append(ir.Struct_item(ir.Typedef_type('sidl_bool'), 'enabled')) contract_cstats.append(ir.Struct_item( ci.methodcstats, 'method_cstats[%d]'%num_methods)) ci.cstats = ir.Struct( ir.Scoped_id(prefix, ci.epv.name+'__cstats', ''), [ir.Struct_item(ir.Typedef_type('sidl_bool'), 'use_hooks')]+contract_cstats, 'The controls and statistics structure') # @class@__object inherits = [] def gen_inherits(baseclass): inherits.append(ir.Struct_item( babel.ir_object_type(baseclass[1], baseclass[2]) [1], # not a pointer, it is an embedded struct 'd_'+str.lower(babel.qual_id(baseclass)))) with_sidl_baseclass = not cls.is_interface() and cls.qualified_name <> ['sidl', 'BaseClass'] # pointers to the base class' EPV par = cls.get_parent() if par and par.is_class(): gen_inherits(par.get_scoped_id()) with_sidl_baseclass = False # pointers to the implemented interface's EPV if not cls.is_interface(): for impl in cls.get_unique_interfaces(): if impl <> (sidlir.scoped_id, ('sidl',), 'BaseInterface', ''): gen_inherits(impl) baseclass = [] if with_sidl_baseclass: baseclass.append( ir.Struct_item(ir.Struct('sidl_BaseClass__object', [],''), 'd_sidl_baseclass')) if ior_template.generateContractEPVs(ci.co): cstats = [ir.Struct_item(unscope(ci.cstats), 'd_cstats')] ior_template.braid_config = self.config epv = [ir.Struct_item(ir.Pointer_type(unscope(ci.epv.get_type())), 'd_epv')] bepv = [ir.Struct_item(ir.Pointer_type(unscope(ci.epv.get_type())), 'd_bepv')] \ if ior_template.generateBaseEPVAttr(ci.co) else [] ci.obj = \ ir.Struct(ir.Scoped_id(prefix, ci.epv.name+'__object', ''), baseclass+ inherits+ epv+ bepv+ cstats+ [ir.Struct_item(ir.Pointer_type(ir.pt_void), 'd_object' if cls.is_interface() else 'd_data')], 'The class object structure') ci.external = \ ir.Struct(ir.Scoped_id(prefix, ci.epv.name+'__external', ''), ([ir.Struct_item(ir.Pointer_type(ir.Fn_decl([], ir.Pointer_type(ci.obj), 'createObject', [ ir.Arg([], ir.inout, ir.void_ptr, 'ddata'), ir.Arg([], sidlir.out, babel.ir_exception_type(), '_ex')], '')), 'createObject')] if not cls.is_abstract else []) + ([ir.Struct_item(ir.Pointer_type(ir.Fn_decl([], ir.Pointer_type(unscope(ci.epv.get_sepv_type())), 'getStaticEPV', [], '')), 'getStaticEPV')] if cls.has_static_methods else []) + [ir.Struct_item( ir.Pointer_type( ir.Fn_decl([], ir.Pointer_type(ir.Struct('sidl_BaseClass__epv', [],'')), 'getSuperEPV', [], '')), 'getSuperEPV'), ir.Struct_item(ir.pt_int, 'd_ior_major_version'), ir.Struct_item(ir.pt_int, 'd_ior_minor_version') ], 'The static class object structure')
def generate_server_method(self, symbol_table, method, ci): """ Generate server code for a method interface. This function generates a C-callable skeleton for the method and generates a Skeleton of Chapel code complete with splicer blocks for the user to fill in. \param method s-expression of the method's SIDL declaration \param symbol_table the symbol table of the SIDL file \param ci a ClassInfo object """ def convert_arg((arg, attrs, mode, typ, name)): """ Extract name and generate argument conversions """ iorname = name return iorname, (arg, attrs, mode, typ, name) # Chapel skeleton (Method, Type, (MName, Name, Extension), Attrs, Args, Except, From, Requires, Ensures, DocComment) = method #ior_args = drop_rarray_ext_args(Args) # ci.epv.add_method((Method, Type, (MName, Name, Extension), Attrs, ior_args, # Except, From, Requires, Ensures, DocComment)) abstract = member_chk(sidlir.abstract, Attrs) static = member_chk(sidlir.static, Attrs) #final = member_chk(sidlir.static, Attrs) if abstract: # nothing to be done for an abstract function return decls = [] pre_call = [] call_args = [] post_call = [] ior_args = babel.lower_ir(symbol_table, Args, lower_scoped_ids=False) ctype = babel.lower_ir(symbol_table, Type, lower_scoped_ids=False) return_stmt = [] skel = ci.chpl_skel opt = skel.cstub.optional qname = '_'.join(ci.co.qualified_name + [Name]) callee = qname + '_impl' # Argument conversions # --------------------- # self this_arg = [] if static else [ir.Arg([], ir.in_, ir.void_ptr, '_this')] # IN map( lambda (arg, attr, mode, typ, name): conv.codegen( (strip(typ), deref(mode, typ, name)), ('chpl', strip(typ)), pre_call, skel, '_CHPL_' + name, typ), filter(incoming, ior_args)) # OUT map( lambda (arg, attr, mode, typ, name): conv.codegen( (('chpl', strip(typ)), '_CHPL_' + name), strip( typ), post_call, skel, '(*%s)' % name, typ), filter(outgoing, ior_args)) # RETURN value type conversion -- treated just like an OUT argument rarg = (ir.arg, [], ir.out, ctype, '_retval') conv.codegen((('chpl', strip(ctype)), '_CHPL__retval'), strip(ctype), post_call, skel, '_retval', ctype) chpl_rarg = conv.ir_arg_to_chpl(rarg) _, _, _, chpltype, _ = chpl_rarg if Type <> sidlir.void: decls.append(ir.Stmt(ir.Var_decl(ctype, '_retval'))) # def pointerize_struct((arg, attr, mode, typ, name)): # # FIXME: this is borked.. instead we should remove this # # _and_ the code in codegenerator that strips the # # pointer_type again # if typ[0] == ir.struct: # return (arg, attr, mode, (ir.pointer_type, typ), name) # else: return (arg, attr, mode, typ, name) # chpl_args = map(pointerize_struct, map(conv.ir_arg_to_chpl, ior_args)) chpl_args = map(conv.ir_arg_to_chpl, ior_args) # Proxy declarations / revised names of call arguments is_retval = True for (_,attrs,mode,chpl_t,name), (_,_,_,c_t,_) \ in zip([chpl_rarg]+chpl_args, [rarg]+ior_args): if chpl_t <> c_t: is_struct = False proxy_t = chpl_t if c_t[0] == ir.pointer_type and c_t[1][0] == ir.struct: # inefficient!!! opt.add(str(c_gen(ir.Type_decl(chpl_t[1])))) c_t = c_t[1] is_struct = True proxy_t = chpl_t[1] # FIXME see comment in chpl_to_ior name = '_CHPL_' + name decls.append(ir.Stmt(ir.Var_decl(proxy_t, name))) if (mode <> sidlir.in_ or is_struct # TODO this should be handled by a conversion rule or (mode == sidlir.in_ and (c_t == ir.pt_fcomplex or c_t == ir.pt_dcomplex))): name = ir.Pointer_expr(name) if name == 'self' and member_chk(ir.pure, attrs): # part of the hack for self dereferencing upcast = ( '({0}*)(((struct sidl_BaseInterface__object*)self)->d_object)' .format(c_gen(c_t[1]))) call_args.append(upcast) else: if is_retval: is_retval = False else: call_args.append(name) call_args.append('_ex') if not static: call_args = ['self->d_data'] + call_args # The actual function call if Type == sidlir.void: Type = ir.pt_void call = [ir.Stmt(ir.Call(callee, call_args))] else: if post_call: call = [ ir.Stmt( ir.Assignment('_CHPL__retval', ir.Call(callee, call_args))) ] return_stmt = [ir.Stmt(ir.Return('_retval'))] else: call = [ir.Stmt(ir.Return(ir.Call(callee, call_args)))] #TODO: ior_args = drop_rarray_ext_args(Args) skeldefn = (ir.fn_defn, [], ctype, qname + '_skel', babel.epv_args(Attrs, Args, ci.epv.symbol_table, ci.epv.name), decls + pre_call + call + post_call + return_stmt, DocComment) def skel_args((arg, attr, mode, typ, name)): # lower array args if typ[0] == sidlir.array: return arg, attr, mode, ir.pt_void, name # complex is always passed as a pointer since chpl 1.5 elif mode == ir.in_ and typ[0] == ir.typedef_type and ( typ[1] == '_complex64' or typ[1] == '_complex128'): return arg, attr, mode, ir.Pointer_type(typ), name else: return arg, attr, mode, typ, name ex_arg = [ir.Arg([], ir.inout, babel.ir_baseinterface_type(), '_ex')] impl_args = this_arg + map(skel_args, chpl_args) + ex_arg impldecl = (ir.fn_decl, [], chpltype, callee, impl_args, DocComment) splicer = '.'.join(ci.epv.symbol_table.prefix + [ci.epv.name, Name]) impldefn = (ir.fn_defn, ['export ' + callee], chpltype, Name, impl_args, [ 'set_to_null(_ex);', '// DO-NOT-DELETE splicer.begin(%s)' % splicer, '// DO-NOT-DELETE splicer.end(%s)' % splicer ], DocComment) c_gen(skeldefn, ci.stub) c_gen(impldecl, ci.stub) upc_gen(impldefn, ci.impl)
def generate_skeleton(self, ci, qname): """ Chapel Skeleton (client-side Chapel bindings) Generate a Skeleton in Chapel. """ symbol_table = ci.epv.symbol_table cls = ci.co # Skeleton (in Chapel) self.pkg_chpl_skel.gen(ir.Import('.'.join(symbol_table.prefix))) self.pkg_chpl_skel.new_def('use sidl;') objname = '.'.join(ci.epv.symbol_table.prefix + [ci.epv.name]) + '_Impl' self.pkg_chpl_skel.new_def( 'extern record %s__object { var d_data: opaque; };' % qname) #,objname)) self.pkg_chpl_skel.new_def('extern proc %s__createObject(' % qname + 'd_data: int, ' + 'out ex: sidl_BaseInterface__object)' + ': %s__object;' % qname) self.pkg_chpl_skel.new_def(ci.chpl_skel) # Skeleton (in C) cskel = ci.chpl_skel.cstub cskel._name = qname + '_Skel' cskel.gen(ir.Import('stdint')) cskel.gen(ir.Import('stdio')) cskel.gen(ir.Import(cskel._name)) cskel.gen(ir.Import(qname + '_IOR')) cskel.gen( ir.Fn_defn([], ir.pt_void, qname + '__call_load', [], [ir.Comment("FIXME: [ir.Stmt(ir.Call('_load', []))")], '')) # set_epv ... Setup the entry-point vectors (EPV)s # # there are 2*3 types of EPVs: # epv: regular methods # sepv: static methods # pre_(s)epv: pre-hooks # post_(s)epv: post-hooks epv_t = ci.epv.get_ir() sepv_t = ci.epv.get_sepv_ir() pre_epv_t = ci.epv.get_pre_epv_ir() pre_sepv_t = ci.epv.get_pre_sepv_ir() post_epv_t = ci.epv.get_post_epv_ir() post_sepv_t = ci.epv.get_post_sepv_ir() cskel.gen(ir.Fn_decl([], ir.pt_void, 'ctor', [], '')) cskel.gen(ir.Fn_decl([], ir.pt_void, 'dtor', [], '')) epv_init = [] sepv_init = [] for m in builtins + cls.get_methods(): fname = m[2][1] + m[2][2] attrs = sidlir.method_method_attrs(m) static = member_chk(sidlir.static, attrs) def entry(stmts, epv_t, table, field, pointer): stmts.append( ir.Set_struct_item_stmt(epv_t, ir.Deref(table), field, pointer)) if static: entry(sepv_init, sepv_t, 'sepv', 'f_' + fname, '%s_%s_skel' % (qname, fname)) else: entry(epv_init, epv_t, 'epv', 'f_' + fname, '%s_%s_skel' % (qname, fname)) builtin_names = ['_ctor', '_ctor2', '_dtor'] with_hooks = member_chk(ir.hooks, attrs) if fname not in builtin_names and with_hooks: if static: entry(sepv_init, pre_sepv_t, 'pre_sepv', 'f_%s_pre' % fname, 'NULL') else: entry(epv_init, pre_epv_t, 'pre_epv', 'f_%s_pre' % fname, 'NULL') if static: entry(sepv_init, post_sepv_t, 'post_sepv', 'f_%s_post' % fname, 'NULL') else: entry(epv_init, post_epv_t, 'post_epv', 'f_%s_post' % fname, 'NULL') pkgname = '_'.join(ci.epv.symbol_table.prefix) dummyargv = ''' char* argv[] = { babel_program_name, "-nl", /* number of locales */ "", "-v", /* verbose chapel runtime */ NULL }; argv[2] = getenv("SLURM_NTASKS"); if (argv[2] == NULL) { fprintf(stdout, "**ERROR: please set the SLURM_NTASKS environment variable\\n" " to the desired number of Chapel locales."); argv[2] = "0"; } int ignored = setenv("GASNET_BACKTRACE", "1", 1); ''' cskel.genh(ir.Import('stdlib')) cskel.pre_def('extern int chpl_init_library(int argc, char* argv[]);') cskel.pre_def( '// You can set this to argv[0] in main() to get better debugging output' ) cskel.pre_def( 'char* __attribute__((weak)) babel_program_name = "BRAID_LIBRARY";' ) # These are now called by chpl_init_library -> chpl_gen_init #cskel.pre_def('extern void chpl__init_chpl__Program(int, const char*);') #cskel.pre_def('extern void chpl__init_%s_Impl(int, const char*);'%pkgname) init_code = [ dummyargv, 'int locale_id = chpl_init_library(4, argv)', # 'chpl__init_chpl__Program(__LINE__, __FILE__)', # 'chpl__init_%s_Impl(__LINE__, __FILE__)'%pkgname ] init_code = map(lambda x: (ir.stmt, x), init_code) epv_init.extend(init_code) sepv_init.extend(init_code) cskel.gen( ir.Fn_defn([], ir.pt_void, qname + '__set_epv', [ ir.Arg([], ir.out, epv_t, 'epv'), ir.Arg([], ir.out, pre_epv_t, 'pre_epv'), ir.Arg([], ir.out, post_epv_t, 'post_epv') ], epv_init, '')) if sepv_t: cskel.gen( ir.Fn_defn([], ir.pt_void, qname + '__set_sepv', [ ir.Arg([], ir.out, sepv_t, 'sepv'), ir.Arg([], ir.out, pre_sepv_t, 'pre_sepv'), ir.Arg([], ir.out, post_sepv_t, 'post_sepv') ], sepv_init, '')) # C Skel for code in cskel.optional: cskel.new_global_def(code) cskel.write()