def mk_harness_pattern(tmpl, cls, smpl): harness = mk_harness(cls, smpl) buf = cStringIO.StringIO() call_stack = [] objs = {} # { @Object(typ, idx): obj_typ_idx, ... } def lkup_obj(v): if type(kind(v)) is unicode: return objs[v] else: return v def to_obj(v): _anno = to_expression(v).anno rep = u"obj_{}_{}".format(_anno.typ, _anno.idx) objs[v] = rep return rep for i, log in enumerate(smpl.logs): if isinstance(log, CallEnt): call_stack.append(log) if len(call_stack) > 1: continue if log.is_init: rcv = to_obj(smpl.logs[i + 1].vals[0]) args = ", ".join(map(lkup_obj, log.vals)) buf.write("{0} {1} = new {0}({2});\n".format( log.cls, rcv, args)) else: # normal call try: args = map(lkup_obj, log.vals) if log.vals and type(kind(log.vals[0])) is unicode: args_mod_rcv = ", ".join(args[1:]) buf.write("{}.{}({});\n".format( args[0], log.mtd, args_mod_rcv)) else: buf.write("{}({});\n".format(log.mtd, ", ".join(args))) except KeyError: continue # means, unknown obj (Evt) occurs elif isinstance(log, CallExt): call_stack.pop() if len(call_stack) > 0: continue else: # Evt buf.write("@React;\n") harness.body = to_statements(harness, unicode(buf.getvalue())) cls.add_mtds([harness])
def mk_harness_pattern(tmpl, cls, smpl): harness = mk_harness(cls, smpl) buf = cStringIO.StringIO() call_stack = [] objs = {} # { @Object(typ, idx): obj_typ_idx, ... } def lkup_obj(v): if type(kind(v)) is unicode: return objs[v] else: return v def to_obj(v): _anno = to_expression(v).anno rep = u"obj_{}_{}".format(_anno.typ, _anno.idx) objs[v] = rep return rep for i, log in enumerate(smpl.logs): if isinstance(log, CallEnt): call_stack.append(log) if len(call_stack) > 1: continue if log.is_init: rcv = to_obj(smpl.logs[i+1].vals[0]) args = ", ".join(map(lkup_obj, log.vals)) buf.write("{0} {1} = new {0}({2});\n".format(log.cls, rcv, args)) else: # normal call try: args = map(lkup_obj, log.vals) if log.vals and type(kind(log.vals[0])) is unicode: args_mod_rcv = ", ".join(args[1:]) buf.write("{}.{}({});\n".format(args[0], log.mtd, args_mod_rcv)) else: buf.write("{}({});\n".format(log.mtd, ", ".join(args))) except KeyError: continue # means, unknown obj (Evt) occurs elif isinstance(log, CallExt): call_stack.pop() if len(call_stack) > 0: continue else: # Evt buf.write("@React;\n") harness.body = to_statements(harness, unicode(buf.getvalue())) cls.add_mtds([harness])
def lkup_obj(v): if type(kind(v)) is unicode: return objs[v] else: return v
def gen_smpl_sk(sk_path, smpl, tmpl, main): buf = cStringIO.StringIO() buf.write("package {};\n".format(smpl.name)) buf.write(_const) buf.write("harness void {} () {{\n".format(smpl.name)) # insert call-return sequences buf.write(""" clear_log@log(); int[P] log = { 0 }; """) global _mids obj_cnt = 0 objs = { C.J.N: 0, C.J.FALSE: 0, C.J.TRUE: 1, } # { @Obj...aaa : 2, ... } for i in xrange(10): objs[str(i)] = i obj_cnt = obj_cnt + 1 call_stack = [] for io in smpl.IOs: # ignore <init> if io.is_init: continue elif isinstance(io, sample.CallExt): # ignore method exits whose counterparts are missed if not call_stack: continue mid = call_stack.pop() # ignore methods that are not declared in the template if not mid: continue else: # sample.CallEnt mid = None # TODO: retrieve arg types mtd = None # find_mtd_by_sig(io.cls, io.mtd, ...) if mtd: # found the method that matches the argument types mid = repr(mtd) if mid not in _mids: continue else: # try other possible methods mtds = find_mtds_by_name(io.cls, io.mtd) argn = len(io.vals) min_gap = argn for mtd in mtds: _gap = abs((argn - (0 if mtd.is_static else 1)) - len(mtd.params)) if _gap <= min_gap: # eq is needed for zero parameter min_gap = _gap mid = repr(mtd) if mid not in _mids: mid = None call_stack.append(mid) # ignore methods that are not declared in the template if not mid: continue if isinstance(io, sample.CallEnt): mid = mid + "_ent()" else: # sample.CallExt mid = mid + "_ext()" vals = [] for val in io.vals: kind = sample.kind(val) if type(kind) is type: val = str(val) # every occurrence of constant string will be uniquely allocated, # hence different hash => assign unique obj_cnt # also, primitive value doesn't have hash, # so we can't compare via obj array; just assign unique obj_cnt ## 1) primitive, including string # 2) this object never occurs #if type(kind) is type or val not in objs: if val not in objs: obj_cnt = obj_cnt + 1 objs[val] = obj_cnt vals.append(str(objs[val])) buf.write(""" log = (int[P]){{ {} }}; write_log@log(log); """.format(", ".join([mid] + vals))) buf.write(""" int len_log = get_log_cnt@log(); reset_log_cnt@log(); """) global max_objs max_objs = max(max_objs, obj_cnt) # invoke class initializers for cls in util.flatten_classes(tmpl.classes, "inners"): clinit = cls.mtd_by_sig(C.J.CLINIT) if not clinit: continue # to only call the base class's <clinit> if clinit.clazz != cls: continue buf.write(" {}();\n".format(trans_mname(unicode(repr(cls)), clinit.name))) # execute template's *main* cname = unicode(repr(main.clazz)) mname = main.name arg_typs = main.param_typs params = main.params + [ (C.J.z, u"logging") ] args = ", ".join(sig_match(params, [])) buf.write("\n {}({});\n".format(trans_mname(cname, mname, arg_typs), args)) buf.write("assert len_log == get_log_cnt@log();") buf.write("\n}\n") with open(sk_path, 'w') as f: f.write(buf.getvalue()) logging.info("encoding " + f.name) buf.close()