Commit fc3528e0 authored by Kunshan Wang's avatar Kunshan Wang

WIP: Updated header and let parser handle pragmas.

Still breaking things.
parent d43dfdba
This diff is collapsed.
......@@ -39,36 +39,91 @@ def extract_pragmas(text):
else:
return text.split(";")
def extract_method(name, params, ret_ty, pragmas):
params = extract_params(params)
ret_ty = filter_ret_ty(ret_ty)
pragmas = extract_pragmas(pragmas)
params_index = {p["name"]:p for p in params}
for pragma in pragmas:
parts = pragma.split(":")
param_name = parts[0]
if param_name not in params_index:
raise Exception("Method {}: Pragma {} is for unknown param {}".format(
name, pragma, param_name))
param = params_index[param_name]
kind = parts[1]
if kind == 'array':
sz_param_name = parts[2]
param["array_sz_param"] = sz_param_name
if sz_param_name not in params_index:
raise Exception(
"Method {}: param {}: Array length parameter {} does not exist".format(
name, pn, sz_param_name))
sz_param = params_index[sz_param_name]
sz_param["is_sz_param"] = True
elif kind == 'optional':
param["is_optional"] = True
elif kind == 'out':
param["is_out"] = True
else:
raise Exception("Method {}: param {}: Unrecognised pragma {}".format(
name, pn, pragma))
return {
"name": name,
"params": params,
"ret_ty": ret_ty,
# "pragmas": pragmas, # Don't include it any more, since we handle everything.
}
def extract_methods(body):
methods = []
for ret, name, params, pragma in r_decl.findall(body):
methods.append({
"name": name,
"params": extract_params(params),
"ret_ty": filter_ret_ty(ret),
"pragmas": extract_pragmas(pragma),
})
for ret, name, params, pragmas in r_decl.findall(body):
method = extract_method(name, params, ret, pragmas)
methods.append(method)
return methods
def extract_struct(text, name):
return injecttools.extract_lines(text, (r_struct_start, name), (r_struct_end,))
def extract_enum(name, ty, value, pragmas):
pragmas = extract_pragmas(pragmas)
enum = {
"name": name,
"value": value,
# "pragmas": pragmas, # Don't include it any more, since we handle everything.
}
for pragma in pragmas:
parts = pragma.split(":")
pragma_name = parts[0]
if pragma_name == "muname":
muname = parts[1]
enum["muname"] = muname
return enum
def extract_enums(text, typename, pattern):
defs = []
for name, ty, value, pragma in r_define.findall(text):
for name, ty, value, pragmas in r_define.findall(text):
if pattern.search(name) is not None:
defs.append({
"name": name,
"value": value,
"pragmas": extract_pragmas(pragma),
})
enum = extract_enum(name, ty, value, pragmas)
defs.append(enum)
return {
"name": typename,
"defs": defs,
}
_top_level_structs = ["MuVM", "MuCtx"]
_top_level_structs = ["MuVM", "MuCtx", "MuIRBuilder"]
_enums = [(typename, re.compile(regex)) for typename, regex in [
("MuTrapHandlerResult", r'^MU_(THREAD|REBIND)'),
("MuDestKind", r'^MU_DEST_'),
......
......@@ -52,22 +52,31 @@ _other_ptr_types = {
_self_getters = {
"MuVM*": "getMicroVM",
"MuCtx*": "getMuCtx",
"MuIRBuilder*": "getMuIRBuilder",
}
def type_is_explicit_ptr(ty):
return ty.endswith("*")
r_handle_ty = re.compile(r'^Mu\w*(Value|Node)$')
r_handle_ty = re.compile(r'^Mu\w*(Value)$')
def type_is_handle(ty):
return r_handle_ty.match(ty) is not None
r_node_ty = re.compile(r'^Mu\w*(Node|Clause)$')
def type_is_node(ty):
return r_node_ty.match(ty) is not None
def type_is_ptr(ty):
return type_is_explicit_ptr(ty) or type_is_handle(ty) or ty in _other_ptr_types
def type_is_handle_array(ty):
return type_is_ptr(ty) and type_is_handle(ty[:-1])
def type_is_node_array(ty):
return type_is_ptr(ty) and type_is_node(ty[:-1])
def to_jffi_ty(raw_type):
if raw_type in _primitive_types:
jty = _primitive_types[raw_type][1]
......@@ -195,8 +204,9 @@ _special_converters = {
_special_return_converters = {
"MuBool" : "booleanToInt",
"MuName" : "exposeString",
"MuCtx*" : "exposeMuCtx",
"MuVM*" : "exposeMicroVM",
"MuCtx*" : "exposeMuCtx",
"MuIRBuilder*" : "exposeMuIRBuilder",
}
def param_converter(pn, pt, rn, rt, is_optional, array_sz, is_out):
......@@ -206,15 +216,20 @@ def param_converter(pn, pt, rn, rt, is_optional, array_sz, is_out):
if pt in _primitive_types or pt in _no_conversion or is_out:
return rn # does not need conversion
if type_is_node(pt):
return rn # does not need conversion
if array_sz is not None:
if type_is_handle_array(pt):
ac = "readMuValueArray"
elif type_is_node_array(pt):
ac = "readMuIDArray"
elif pt in _array_converters:
ac = _array_converters[pt]
else:
raise ValueError("I don't know how to convert array {}. "
"Param name: {}, array size: {}".format(pt, pn, array_sz))
return "{}({}, {})".format(ac, rn, array_sz)
return "{}({}, {})".format(ac, rn, "_raw_"+array_sz)
if type_is_handle(pt):
if is_optional:
......@@ -232,7 +247,6 @@ def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
name = meth['name']
params = meth['params']
ret_ty = meth['ret_ty']
pragmas = meth['pragmas']
valname = strname.upper() + "__" + name.upper()
......@@ -246,11 +260,6 @@ def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
stmts = []
# pragmas
pragmas = [tuple(p.split(":")) for p in pragmas]
array_szs = [p[2] for p in pragmas if p[1] == 'array']
# get raw parameters
for i in range(len(params)):
param = params[i]
......@@ -281,7 +290,7 @@ def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
param = params[i]
pn = param['name']
if pn in array_szs:
if param.get("is_sz_param", False):
continue # Array sizes don't need to be passed explicitly.
args_to_pass.append(pn)
......@@ -290,20 +299,9 @@ def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
rn = "_raw_" + pn
rt = to_basic_type(typedefs, pt)
pps = [p for p in pragmas if p[0] == pn]
is_optional = False
array_sz = None
is_out = False
for pp in pps:
if pp[1] == 'array':
array_sz = "_raw_" + pp[2]
elif pp[1] == 'optional':
is_optional = True
elif pp[1] == 'bool':
raise ValueError("bool pragma is deprecated")
is_bool = True
elif pp[1] == 'out':
is_out = True
array_sz = param.get("array_sz_param", None)
is_optional = param.get("is_optional", False)
is_out = param.get("is_out", False)
pc = param_converter(pn, pt, rn, rt, is_optional, array_sz, is_out)
......@@ -332,8 +330,6 @@ def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
stmts.append("val _RV_FAK = {}(_RV)".format(
_special_return_converters[ret_ty]))
stmts.append("_jffiBuffer.{}(_RV_FAK)".format(jffi_setter))
elif ("RV", "bool") in pragmas:
stmts.append("_jffiBuffer.{}(if(_RV) 1 else 0)".format(jffi_setter))
else:
stmts.append("_jffiBuffer.{}(_RV)".format(jffi_setter))
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment