Skip to content

Python 3.9 #1264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 13, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix geninterop script and regenerate interop39.cs
- Only record structs when they are defined, not when they are declared
- If a struct was only declared when a typedef was created, it won't
  contain its member declarations. Those have to be drawn from the
  recorded structs instead.
- Rename internal members of AstParser to make it easier to debug
  • Loading branch information
filmor committed Nov 13, 2020
commit 094bf2cee96e1996241db92a41b6448e4000bd01
52 changes: 51 additions & 1 deletion src/runtime/interop39.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,57 @@ namespace Python.Runtime
internal static partial class TypeOffset
{
// Auto-generated from PyHeapTypeObject in Python.h
public static int ob_refcnt = 0;
public static int ob_type = 0;
public static int ob_size = 0;
public static int tp_name = 0;
public static int tp_basicsize = 0;
public static int tp_itemsize = 0;
public static int tp_dealloc = 0;
public static int tp_vectorcall_offset = 0;
public static int tp_getattr = 0;
public static int tp_setattr = 0;
public static int tp_as_async = 0;
public static int tp_repr = 0;
public static int tp_as_number = 0;
public static int tp_as_sequence = 0;
public static int tp_as_mapping = 0;
public static int tp_hash = 0;
public static int tp_call = 0;
public static int tp_str = 0;
public static int tp_getattro = 0;
public static int tp_setattro = 0;
public static int tp_as_buffer = 0;
public static int tp_flags = 0;
public static int tp_doc = 0;
public static int tp_traverse = 0;
public static int tp_clear = 0;
public static int tp_richcompare = 0;
public static int tp_weaklistoffset = 0;
public static int tp_iter = 0;
public static int tp_iternext = 0;
public static int tp_methods = 0;
public static int tp_members = 0;
public static int tp_getset = 0;
public static int tp_base = 0;
public static int tp_dict = 0;
public static int tp_descr_get = 0;
public static int tp_descr_set = 0;
public static int tp_dictoffset = 0;
public static int tp_init = 0;
public static int tp_alloc = 0;
public static int tp_new = 0;
public static int tp_free = 0;
public static int tp_is_gc = 0;
public static int tp_bases = 0;
public static int tp_mro = 0;
public static int tp_cache = 0;
public static int tp_subclasses = 0;
public static int tp_weaklist = 0;
public static int tp_del = 0;
public static int tp_version_tag = 0;
public static int tp_finalize = 0;
public static int tp_vectorcall = 0;
public static int am_await = 0;
public static int am_aiter = 0;
public static int am_anext = 0;
Expand Down Expand Up @@ -174,4 +225,3 @@ internal static partial class SlotTypes

}
#endif

88 changes: 47 additions & 41 deletions tools/geninterop/geninterop.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,25 @@ class AstParser(object):
"""Walk an AST and determine the members of all structs"""

def __init__(self):
self.__typedefs = {}
self.__typedecls = {}
self.__structs = {}
self.__struct_stack = []
self.__struct_members_stack = []
self.__ptr_decl_depth = 0
self.__struct_members = {}
self.__decl_names = {}
self._typedefs = {}
self._typedecls = {}
self._structs = {}
self._struct_stack = []
self._struct_members_stack = []
self._ptr_decl_depth = 0
self._struct_members = {}
self._decl_names = {}

def get_struct_members(self, name):
"""return a list of (name, type) of struct members"""
defs = self.__typedefs.get(name)
defs = self._typedefs.get(name)
if defs is None:
return None
node = self.__get_leaf_node(defs)
node = self._get_leaf_node(defs)
name = node.name
if name is None:
name = defs.declname
return self.__struct_members.get(name)
return self._struct_members.get(name)

def visit(self, node):
if isinstance(node, c_ast.FileAST):
Expand All @@ -96,27 +96,27 @@ def visit_ast(self, ast):
self.visit(node)

def visit_typedef(self, typedef):
self.__typedefs[typedef.name] = typedef.type
self._typedefs[typedef.name] = typedef.type
self.visit(typedef.type)

def visit_typedecl(self, typedecl):
self.__decl_names[typedecl.type] = typedecl.declname
self._decl_names[typedecl.type] = typedecl.declname
self.visit(typedecl.type)

def visit_struct(self, struct):
self.__structs[self.__get_struct_name(struct)] = struct
if struct.decls:
self._structs[self._get_struct_name(struct)] = struct
# recurse into the struct
self.__struct_stack.insert(0, struct)
self._struct_stack.insert(0, struct)
for decl in struct.decls:
self.__struct_members_stack.insert(0, decl.name)
self._struct_members_stack.insert(0, decl.name)
self.visit(decl)
self.__struct_members_stack.pop(0)
self.__struct_stack.pop(0)
elif self.__ptr_decl_depth:
self._struct_members_stack.pop(0)
self._struct_stack.pop(0)
elif self._ptr_decl_depth:
# the struct is empty, but add it as a member to the current
# struct as the current member maybe a pointer to it.
self.__add_struct_member(struct.name)
self._add_struct_member(struct.name)

def visit_decl(self, decl):
self.visit(decl.type)
Expand All @@ -125,51 +125,57 @@ def visit_funcdecl(self, funcdecl):
self.visit(funcdecl.type)

def visit_ptrdecl(self, ptrdecl):
self.__ptr_decl_depth += 1
self._ptr_decl_depth += 1
self.visit(ptrdecl.type)
self.__ptr_decl_depth -= 1
self._ptr_decl_depth -= 1

def visit_identifier(self, identifier):
type_name = " ".join(identifier.names)
self.__add_struct_member(type_name)
self._add_struct_member(type_name)

def __add_struct_member(self, type_name):
if not (self.__struct_stack and self.__struct_members_stack):
def _add_struct_member(self, type_name):
if not (self._struct_stack and self._struct_members_stack):
return

# add member to current struct
current_struct = self.__struct_stack[0]
member_name = self.__struct_members_stack[0]
struct_members = self.__struct_members.setdefault(
self.__get_struct_name(current_struct), [])
current_struct = self._struct_stack[0]
member_name = self._struct_members_stack[0]
struct_members = self._struct_members.setdefault(
self._get_struct_name(current_struct), [])

# get the node associated with this type
node = None
if type_name in self.__typedefs:
node = self.__get_leaf_node(self.__typedefs[type_name])
elif type_name in self.__structs:
node = self.__structs[type_name]
if type_name in self._typedefs:
node = self._get_leaf_node(self._typedefs[type_name])
# If the struct was only declared when the typedef was created, its member
# information will not have been recorded and we have to look it up in the
# structs
if isinstance(node, c_ast.Struct) and node.decls is None:
if node.name in self._structs:
node = self._structs[node.name]
elif type_name in self._structs:
node = self._structs[type_name]

# If it's a struct (and not a pointer to a struct) expand
# it into the current struct definition
if not self.__ptr_decl_depth and isinstance(node, c_ast.Struct):
if not self._ptr_decl_depth and isinstance(node, c_ast.Struct):
for decl in node.decls or []:
self.__struct_members_stack.insert(0, decl.name)
self._struct_members_stack.insert(0, decl.name)
self.visit(decl)
self.__struct_members_stack.pop(0)
self._struct_members_stack.pop(0)
else:
# otherwise add it as a single member
struct_members.append((member_name, type_name))

def __get_leaf_node(self, node):
def _get_leaf_node(self, node):
if isinstance(node, c_ast.Typedef):
return self.__get_leaf_node(node.type)
return self._get_leaf_node(node.type)
if isinstance(node, c_ast.TypeDecl):
return self.__get_leaf_node(node.type)
return self._get_leaf_node(node.type)
return node

def __get_struct_name(self, node):
return node.name or self.__decl_names.get(node) or "_struct_%d" % id(node)
def _get_struct_name(self, node):
return node.name or self._decl_names.get(node) or "_struct_%d" % id(node)


class Writer(object):
Expand Down