Ejemplo n.º 1
0
def wrap_function(ctype, orig_ctype, func):

    # only care about non-variadic functions if they return wrappable types.
    # otherwise, we always care about manually wrapping variadic functions
    # and functions that don't return.
    if not ctype.is_variadic \
    and not has_extension_attribute(orig_ctype, "noreturn"):
        #if not will_wrap_function(ctype.ret_type, []):
        return

    # don't wrap deprecated functions; the compiler will complain about them.
    if has_extension_attribute(orig_ctype, "deprecated"):
        return

    if not must_wrap([ctype.ret_type] + ctype.param_types):
        return

    # internal function
    #elif func.startswith("__"):
    #  return

    O = OUT

    internal_ret_type = ctype.ret_type.base_type()
    suffix, is_void = "", False
    if isinstance(internal_ret_type, CTypeBuiltIn) \
    and "void" == internal_ret_type.name:
        suffix, is_void = "_VOID", True

    variadic = ""
    if ctype.is_variadic:
        if ctype.param_types:
            variadic = ", "
        variadic += "..."

    arg_list = []
    num_params = [0]

    def next_param(p):
        if p:
            return p
        else:
            num_params[0] += 1
            return "_arg%d" % num_params[0]

    param_names = map(next_param, ctype.param_names)
    last_arg_name = ""
    for (arg_ctype, arg_name) in zip(ctype.param_types, param_names):
        if not arg_name:
            arg_name = ""
        last_arg_name = arg_name
        arg_list.append(
            pretty_print_type(arg_ctype, arg_name, lang="C++").strip(" "))
    args = ", ".join(arg_list)

    # get an output string for the return type.
    ret_type = ""
    if not is_void:
        ret_type = pretty_print_type(ctype.ret_type, "", lang="C++").strip(" ")
        ret_type = " (%s), " % ret_type

    addr_check = ""
    if func.startswith("__"):
        addr_check = " && defined(DETACH_ADDR_%s)" % func

    # TODO: re-enable auto-wrapping of variadic functions?
    if ctype.is_variadic:
        return

    O("#if defined(CAN_WRAP_", func, ") && CAN_WRAP_", func, addr_check)
    O("#ifndef APP_WRAPPER_FOR_", func)
    O("#define APP_WRAPPER_FOR_", func)
    O("FUNCTION_WRAPPER", suffix, "(APP, ", func, ",", ret_type, "(", args,
      variadic, "), {")

    if ctype.is_variadic:
        O("    va_list args__;")
        O("    va_start(args__, %s);" % last_arg_name)

    # assignment of return value; unattributed_type is used in place of base type
    # so that we don't end up with anonymous structs/unions/enums.
    a, r_v = "", ""
    if not is_void:
        r_v = "ret"
        a = pretty_print_type(ctype.ret_type.unattributed_type(), r_v,
                              "C++") + " = "

    for (arg_ctype, arg_name) in zip(ctype.param_types, param_names):
        pre_wrap_var(arg_ctype, arg_name, O, indent="    ")

    global VA_LIST_FUNCS
    va_func = "v%s" % func

    special = False
    if ctype.is_variadic and va_func in VA_LIST_FUNCS:
        O("    IF_KERNEL( auto ", va_func, "((decltype(::", va_func,
          ") *) DETACH_ADDR_", va_func, "); ) ")
        O("    ", a, va_func, "(", ", ".join(param_names + ["args__"]), ");")
    else:
        if ctype.is_variadic:
            special = True
            O("    // TODO: variadic arguments")
        O("    D( granary_fault(); )")
        O("    ", a, func, "(", ", ".join(param_names), ");")

    if ctype.is_variadic:
        O("    va_end(args__);")

    #O("    D( granary::printf(\"FUNCTION_WRAPPER(APP, %s) %s\\n\"); )" % (func, special and "*" or ""))

    if not is_void and not isinstance(ctype.ret_type.base_type(),
                                      CTypeBuiltIn):
        O("    RETURN_IN_WRAP(", r_v, ");")

    if not is_void:
        O("    return ", r_v, ";")

    O("})")
    O("#endif")
    O("#endif")
    O()
    O()
Ejemplo n.º 2
0
def wrap_function(ctype, orig_ctype, func):

  # only care about non-variadic functions if they return wrappable types.
  # otherwise, we always care about manually wrapping variadic functions
  # and functions that don't return.
  if not ctype.is_variadic \
  and not has_extension_attribute(orig_ctype, "noreturn"):
    #if not will_wrap_function(ctype.ret_type, []):
    return

  # don't wrap deprecated functions; the compiler will complain about them.
  if has_extension_attribute(orig_ctype, "deprecated"):
    return

  if not must_wrap([ctype.ret_type] + ctype.param_types):
    return

  # internal function
  #elif func.startswith("__"):
  #  return

  O = OUT

  internal_ret_type = ctype.ret_type.base_type()
  suffix, is_void = "", False
  if isinstance(internal_ret_type, CTypeBuiltIn) \
  and "void" == internal_ret_type.name:
    suffix, is_void = "_VOID", True

  variadic = ""
  if ctype.is_variadic:
    if ctype.param_types:
      variadic = ", "
    variadic += "..."

  arg_list = []
  num_params = [0]
  def next_param(p):
    if p:
      return p
    else:
      num_params[0] += 1
      return "_arg%d" % num_params[0]

  param_names = map(next_param, ctype.param_names)
  last_arg_name = ""
  for (arg_ctype, arg_name) in zip(ctype.param_types, param_names):
    if not arg_name:
      arg_name = ""
    last_arg_name = arg_name
    arg_list.append(pretty_print_type(arg_ctype, arg_name, lang="C++").strip(" "))
  args = ", ".join(arg_list)

  # get an output string for the return type.
  ret_type = ""
  if not is_void:
    ret_type = pretty_print_type(ctype.ret_type, "", lang="C++").strip(" ")
    ret_type = " (%s), " % ret_type

  addr_check = ""
  if func.startswith("__"):
    addr_check = " && defined(DETACH_ADDR_%s)" % func

  O("#if defined(CAN_WRAP_", func, ") && CAN_WRAP_", func, addr_check)
  O("#ifndef APP_WRAPPER_FOR_", func)
  O("#define APP_WRAPPER_FOR_", func)
  O("FUNCTION_WRAPPER", suffix, "(APP, ", func, ",", ret_type,"(", args, variadic, "), {")

  if ctype.is_variadic:
    O("    va_list args__;")
    O("    va_start(args__, %s);" % last_arg_name)
  
  # assignment of return value; unattributed_type is used in place of base type
  # so that we don't end up with anonymous structs/unions/enums.
  a, r_v = "", ""
  if not is_void:
    r_v = "ret"
    a = pretty_print_type(ctype.ret_type.unattributed_type(), r_v, "C++") + " = "
  
  for (arg_ctype, arg_name) in zip(ctype.param_types, param_names):
    pre_wrap_var(arg_ctype, arg_name, O, indent="    ")

  global VA_LIST_FUNCS
  va_func = "v%s" % func

  special = False
  if ctype.is_variadic and va_func in VA_LIST_FUNCS:
    O("    IF_KERNEL( auto ", va_func, "((decltype(::", va_func, ") *) DETACH_ADDR_", va_func,"); ) ")
    O("    ", a, va_func, "(", ", ".join(param_names + ["args__"]), ");")
  else:
    if ctype.is_variadic:
      special = True
      O("    // TODO: variadic arguments")
    O("    D( granary_fault(); )")
    O("    ", a, func, "(", ", ".join(param_names), ");")

  if ctype.is_variadic:
    O("    va_end(args__);")

  #O("    D( granary::printf(\"FUNCTION_WRAPPER(APP, %s) %s\\n\"); )" % (func, special and "*" or ""))  

  if not is_void and not isinstance(ctype.ret_type.base_type(), CTypeBuiltIn):
    O("    RETURN_IN_WRAP(", r_v, ");")

  if not is_void:
    O("    return ", r_v, ";")

  O("})")
  O("#endif")
  O("#endif")
  O()
  O()
Ejemplo n.º 3
0
def wrap_function(ctype, orig_ctype, func):

  # only care about non-variadic functions if they return wrappable types.
  # otherwise, we always care about manually wrapping variadic functions
  # and functions that don't return.
  if not ctype.is_variadic \
  and not has_extension_attribute(orig_ctype, "noreturn"):
    #if not will_wrap_function(ctype.ret_type, []):
    return

  # don't wrap deprecated functions; the compiler will complain about them.
  if has_extension_attribute(orig_ctype, "deprecated"):
    return

  if not must_wrap([ctype.ret_type] + ctype.param_types):
    return

  # internal function
  #elif func.startswith("__"):
  #  return

  O = OUT

  internal_ret_type = ctype.ret_type.base_type()
  suffix, is_void = "", False
  if isinstance(internal_ret_type, CTypeBuiltIn) \
  and "void" == internal_ret_type.name:
    suffix, is_void = "_VOID", True

  variadic = ""
  if ctype.is_variadic:
    if ctype.param_types:
      variadic = ", "
    variadic += "..."

  arg_list = []
  num_params = [0]
  def next_param(p):
    if p:
      return p
    else:
      num_params[0] += 1
      return "_arg%d" % num_params[0]

  param_names = map(next_param, ctype.param_names)
  last_arg_name = ""
  for (arg_ctype, arg_name) in zip(ctype.param_types, param_names):
    if not arg_name:
      arg_name = ""
    last_arg_name = arg_name
    arg_list.append(pretty_print_type(arg_ctype, arg_name, lang="C++").strip(" "))
  args = ", ".join(arg_list)

  # get an output string for the return type.
  ret_type = ""
  if not is_void:
    ret_type = pretty_print_type(ctype.ret_type, "", lang="C++").strip(" ")
    ret_type = " (%s), " % ret_type

  addr_check = ""
  if func.startswith("__"):
    addr_check = " && defined(DETACH_ADDR_%s)" % func

  O("FUNCTION_WRAPPER", suffix, "(", func, ",", ret_type ,"(", args, variadic, "), {")

  # assignment of return value; unattributed_type is used in place of base type
  # so that we don't end up with anonymous structs/unions/enums.

  O("})")
  O("#endif")
  O("#endif")
  O()
  O()