Esempio n. 1
0
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])
Esempio n. 2
0
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])
Esempio n. 3
0
 def lkup_obj(v):
   if type(kind(v)) is unicode: return objs[v]
   else: return v
Esempio n. 4
0
 def lkup_obj(v):
     if type(kind(v)) is unicode: return objs[v]
     else: return v
Esempio n. 5
0
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()