Пример #1
0
    def get_binding_api_declaration(self):
        type_info_name = gen.apply_api_prefix('type_info')

        out = '''\
struct %s {
	uint32_t type_tag;
	const char *c_type;
	const char *bound_name;

	bool (*check)(PyObject *o);
	void (*to_c)(PyObject *o, void *out);
	PyObject *(*from_c)(void *obj, OwnershipPolicy policy);
};\n
''' % type_info_name

        out += '// return a type info from its bound name\n'
        out += '%s *%s(uint32_t type_tag);\n' % (
            type_info_name, gen.apply_api_prefix('get_bound_type_info'))

        out += '// return a type info from its C name\n'
        out += '%s *%s(const char *type);\n' % (
            type_info_name, gen.apply_api_prefix('get_c_type_info'))

        out += '// returns the typetag of a Python object, nullptr if not a Fabgen object\n'
        out += 'uint32_t %s(PyObject *o);\n\n' % gen.apply_api_prefix(
            'get_wrapped_object_type_tag')

        return out
Пример #2
0
	def get_binding_api_declaration(self):
		type_info_name = gen.apply_api_prefix('type_info')

		out = '''\
struct %s {
	uint32_t type_tag;
	const char *c_type;
	const char *bound_name;

	bool (*check)(lua_State *L, int index);
	void (*to_c)(lua_State *L, int index, void *out);
	int (*from_c)(lua_State *L, void *obj, OwnershipPolicy policy);
};\n
''' % type_info_name

		out += '// return a type info from its type tag\n'
		out += '%s *%s(uint32_t type_tag);\n' % (type_info_name, gen.apply_api_prefix('get_bound_type_info'))

		out += '// return a type info from its type name\n'
		out += '%s *%s(const char *type);\n' % (type_info_name, gen.apply_api_prefix('get_c_type_info'))

		out += '// returns the typetag of a userdata object on the stack, nullptr if not a Fabgen object\n'
		out += 'uint32_t %s(lua_State *L, int idx);\n\n' % gen.apply_api_prefix('get_wrapped_object_type_tag')

		return out
Пример #3
0
    def output_binding_api(self):
        type_info_name = gen.apply_api_prefix('type_info')

        self._source += '// Note: Types using a storage class for conversion are not listed here.\n'
        self._source += 'static std::map<uint32_t, %s> __type_tag_infos;\n\n' % type_info_name

        self._source += 'static void __initialize_type_tag_infos() {\n'
        entries = []
        for type in self._bound_types:
            if not type.c_storage_class:
                self._source += '	__type_tag_infos[%s] = {%s, "%s", "%s", %s, %s, %s};\n' % (
                    type.type_tag, type.type_tag, str(
                        type.ctype), type.bound_name, type.check_func,
                    type.to_c_func, type.from_c_func)
        self._source += '};\n\n'

        self._source += '''\
%s *%s(uint32_t type_tag) {
	auto i = __type_tag_infos.find(type_tag);
	return i == __type_tag_infos.end() ? nullptr : &i->second;
}\n\n''' % (type_info_name, gen.apply_api_prefix('get_bound_type_info'))

        self._source += 'static std::map<std::string, %s> __type_infos;\n\n' % type_info_name

        self._source += 'static void __initialize_type_infos() {\n'
        for type in self._bound_types:
            if not type.c_storage_class:
                self._source += '	__type_infos["%s"] = {%s, "%s", "%s", %s, %s, %s};\n' % (
                    str(type.ctype), type.type_tag, str(
                        type.ctype), type.bound_name, type.check_func,
                    type.to_c_func, type.from_c_func)
        self._source += '};\n\n'

        self._source += '''
%s *%s(const char *type) {
	auto i = __type_infos.find(type);
	return i == __type_infos.end() ? nullptr : &i->second;
}\n\n''' % (type_info_name, gen.apply_api_prefix('get_c_type_info'))

        self._source += '''\
uint32_t %s(PyObject *o) {
	auto w = cast_to_wrapped_Object_safe(o);
	return w ? w->type_tag : 0;
}\n\n''' % gen.apply_api_prefix('get_wrapped_object_type_tag')
Пример #4
0
	def finalize(self):
		super().finalize()

		self.output_binding_api()

		# output module functions table
		self._source += 'static const luaL_Reg %s_global_functions[] = {\n' % self._name
		for f in self._bound_functions:
			self._source += '	{"%s", %s},\n' % (f['bound_name'], f['proxy_name'])
		self._source += '	{NULL, NULL}};\n\n'

		# registration function
		self._source += '''\
#if WIN32
 #define _DLL_EXPORT_ __declspec(dllexport)
#else
 #define _DLL_EXPORT_
#endif
\n'''

		self._source += '''static void declare_enum_value(lua_State *L, int idx, const char *name, int value) {
	lua_pushinteger(L, value);
	lua_setfield(L, idx, name);
}\n\n'''

		# variable lookup map
		self._source += build_index_map('__index_%s_var_map' % self._name, self._bound_variables, lambda v: True, lambda v: '	{"%s", %s}' % (v['bound_name'], v['getter']))
		self._source += build_index_map('__newindex_%s_var_map' % self._name, self._bound_variables, lambda v: v['setter'], lambda v: '	{"%s", %s}' % (v['bound_name'], v['setter']))

		self._source += '''\
static int __index_%s_var(lua_State *L) {
	if (lua_isstring(L, -1)) {
		std::string key = lua_tostring(L, -1);
		lua_pop(L, 1);

		auto i = __index_%s_var_map.find(key); // variable lookup
		if (i != __index_%s_var_map.end())
			return i->second(L);
	}
	return 0; // lookup failed
}\n\n''' % (self._name, self._name, self._name)

		self._source += '''\
static int __newindex_%s_var(lua_State *L) {
	if (lua_isstring(L, -2)) {
		std::string key = lua_tostring(L, -2);
		lua_remove(L, -2);

		auto i = __newindex_%s_var_map.find(key);
		if (i != __newindex_%s_var_map.end())
			return i->second(L);
	}
	return 0; // lookup failed
}\n\n''' % (self._name, self._name, self._name)

		self.output_module_free()

		self._source += '''\
static const luaL_Reg %s_module_meta[] = {
	{"__gc", __gc_%s},
	{"__index", __index_%s_var},
	{"__newindex", __newindex_%s_var},
	{NULL, NULL}
};\n\n''' % (self._name, self._name, self._name, self._name)

		#
		if self.embedded:  # pragma: no cover
			create_module_func = gen.apply_api_prefix('create_%s' % self._name)
			bind_module_func = gen.apply_api_prefix('bind_%s' % self._name)

			self._header += '// create the module object and push it onto the stack\n'
			self._header += 'int %s(lua_State *L);\n' % create_module_func
			self._header += '// create the module object and register it into the interpreter global table\n'
			self._header += 'bool %s(lua_State *L, const char *symbol);\n\n' % bind_module_func

			self._source += 'int %s(lua_State *L) {\n' % create_module_func
		else:
			self._source += 'extern "C" _DLL_EXPORT_ int luaopen_%s(lua_State *L) {\n' % self._name

		self._source += '	// initialize type info structures\n'
		self._source += '	__initialize_type_tag_infos();\n'
		self._source += '	__initialize_type_infos();\n'
		self._source += '\n'

		self._source += '	// custom initialization code\n'
		self._source += self._custom_init_code
		self._source += '\n'

		# create the module table
		self._source += '	// new module table\n'
		self._source += '	lua_newtable(L);\n'
		self._source += '\n'

		# enums
		if len(self._enums) > 0:
			for name, enum in self._enums.items():
				self._source += '	// enumeration %s\n' % name
				for name, value in enum.items():
					self._source += '	declare_enum_value(L, -2, "%s", (int)%s);\n' % (name, value)
			self._source += '\n'

		types_to_register = [t for t in self._bound_types if isinstance(t, LuaClassTypeConverter)]

		if len(types_to_register) > 0:
			self._source += '	// register types\n'
			for t in types_to_register:
				self._source += '	register_%s(L);\n' % t.bound_name
			self._source += '\n'

		self._source += '	// register global functions\n'
		self._source += '	luaL_setfuncs(L, %s_global_functions, 0);\n' % self._name
		self._source += '\n'

		# module metatable
		self._source += '	// setup module metatable\n'
		self._source += '	lua_newtable(L);\n'
		self._source += '	luaL_setfuncs(L, %s_module_meta, 0);\n' % self._name
		self._source += '	lua_setmetatable(L, -2);\n'

		self._source += '	return 1;\n'
		self._source += '}\n\n'

		#
		if self.embedded:  # pragma: no cover
			self._source += '''\
bool %s(lua_State *L, const char *symbol) {
	if (%s(L) != 1)
		return false;
	lua_setglobal(L, symbol);
	return true;
}\n
''' % (bind_module_func, create_module_func)