mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 04:48:08 +02:00
mapi: Add a generic C dispatcher.
The idea is to have an API generate a header using mapi_abi.py. The API can then use the header to build a dispatcher.
This commit is contained in:
parent
a73c6540d9
commit
d4589d3816
12 changed files with 1325 additions and 0 deletions
52
src/mapi/mapi/entry.c
Normal file
52
src/mapi/mapi/entry.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "u_current.h"
|
||||
#include "entry.h"
|
||||
#include "table.h"
|
||||
|
||||
/* C version of the public entries */
|
||||
#define MAPI_TMP_PUBLIC_ENTRIES
|
||||
#include "mapi_tmp.h"
|
||||
|
||||
void
|
||||
entry_patch_public(void)
|
||||
{
|
||||
}
|
||||
|
||||
mapi_func
|
||||
entry_generate(int slot)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
entry_patch(mapi_func entry, int slot)
|
||||
{
|
||||
}
|
||||
49
src/mapi/mapi/entry.h
Normal file
49
src/mapi/mapi/entry.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#ifndef _ENTRY_H_
|
||||
#define _ENTRY_H_
|
||||
|
||||
#include "u_compiler.h"
|
||||
#include "stub.h"
|
||||
|
||||
/* declare public entries */
|
||||
#define MAPI_TMP_DEFINES
|
||||
#define MAPI_TMP_PUBLIC_DECLARES
|
||||
#include "mapi_tmp.h"
|
||||
|
||||
void
|
||||
entry_patch_public(void);
|
||||
|
||||
mapi_func
|
||||
entry_generate(int slot);
|
||||
|
||||
void
|
||||
entry_patch(mapi_func entry, int slot);
|
||||
|
||||
#endif /* _ENTRY_H_ */
|
||||
191
src/mapi/mapi/mapi.c
Normal file
191
src/mapi/mapi/mapi.c
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "u_current.h"
|
||||
#include "u_thread.h"
|
||||
#include "mapi.h"
|
||||
#include "stub.h"
|
||||
#include "table.h"
|
||||
|
||||
/* dynamic stubs will run out before this array */
|
||||
#define MAPI_MAX_STUBS (sizeof(struct mapi_table) / sizeof(mapi_func))
|
||||
static const struct mapi_stub *mapi_stub_map[MAPI_MAX_STUBS];
|
||||
static int mapi_num_stubs;
|
||||
|
||||
static const struct mapi_stub *
|
||||
get_stub(const char *name, const struct mapi_stub *alias)
|
||||
{
|
||||
const struct mapi_stub *stub;
|
||||
|
||||
stub = stub_find_public(name);
|
||||
if (!stub) {
|
||||
struct mapi_stub *dyn = stub_find_dynamic(name, 1);
|
||||
if (dyn) {
|
||||
stub_fix_dynamic(dyn, alias);
|
||||
stub = dyn;
|
||||
}
|
||||
}
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize mapi. spec consists of NULL-separated strings. The first string
|
||||
* denotes the version. It is followed by variable numbers of entries. Each
|
||||
* entry can have multiple names. An empty name terminates an entry. An empty
|
||||
* entry terminates the spec. A spec of two entries, Foo and Bar, is as
|
||||
* follows
|
||||
*
|
||||
* "1\0"
|
||||
* "Foo\0"
|
||||
* "FooEXT\0"
|
||||
* "\0"
|
||||
* "Bar\0"
|
||||
* "\0"
|
||||
*/
|
||||
void
|
||||
mapi_init(const char *spec)
|
||||
{
|
||||
u_mutex_declare_static(mutex);
|
||||
const char *p;
|
||||
int ver, count;
|
||||
|
||||
u_mutex_lock(mutex);
|
||||
|
||||
/* already initialized */
|
||||
if (mapi_num_stubs) {
|
||||
u_mutex_unlock(mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
p = spec;
|
||||
|
||||
/* parse version string */
|
||||
ver = atoi(p);
|
||||
if (ver != 1) {
|
||||
u_mutex_unlock(mutex);
|
||||
return;
|
||||
}
|
||||
p += strlen(p) + 1;
|
||||
|
||||
while (*p) {
|
||||
const struct mapi_stub *stub;
|
||||
|
||||
stub = get_stub(p, NULL);
|
||||
/* out of dynamic entries */
|
||||
if (!stub)
|
||||
break;
|
||||
p += strlen(p) + 1;
|
||||
|
||||
while (*p) {
|
||||
get_stub(p, stub);
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
|
||||
mapi_stub_map[count++] = stub;
|
||||
p++;
|
||||
}
|
||||
|
||||
mapi_num_stubs = count;
|
||||
|
||||
u_mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the address of an entry. Optionally generate the entry if it does
|
||||
* not exist.
|
||||
*/
|
||||
mapi_proc
|
||||
mapi_get_proc_address(const char *name)
|
||||
{
|
||||
const struct mapi_stub *stub;
|
||||
|
||||
stub = stub_find_public(name);
|
||||
if (!stub)
|
||||
stub = stub_find_dynamic(name, 0);
|
||||
|
||||
return (stub) ? (mapi_proc) stub->addr : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dispatch table.
|
||||
*/
|
||||
struct mapi_table *
|
||||
mapi_table_create(void)
|
||||
{
|
||||
const struct mapi_table *noop = table_get_noop();
|
||||
struct mapi_table *tbl;
|
||||
|
||||
tbl = malloc(sizeof(*tbl));
|
||||
if (tbl)
|
||||
memcpy(tbl, noop, sizeof(*tbl));
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a dispatch table.
|
||||
*/
|
||||
void
|
||||
mapi_table_destroy(struct mapi_table *tbl)
|
||||
{
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill a dispatch table. The order of the procs is determined when mapi_init
|
||||
* is called.
|
||||
*/
|
||||
void
|
||||
mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs)
|
||||
{
|
||||
const struct mapi_table *noop = table_get_noop();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mapi_num_stubs; i++) {
|
||||
const struct mapi_stub *stub = mapi_stub_map[i];
|
||||
mapi_func func = (mapi_func) procs[i];
|
||||
|
||||
if (!func)
|
||||
func = table_get_func(noop, stub);
|
||||
table_set_func(tbl, stub, func);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a dispatch table current.
|
||||
*/
|
||||
void
|
||||
mapi_table_make_current(const struct mapi_table *tbl)
|
||||
{
|
||||
u_current_set(tbl);
|
||||
}
|
||||
56
src/mapi/mapi/mapi.h
Normal file
56
src/mapi/mapi/mapi.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#ifndef _MAPI_H_
|
||||
#define _MAPI_H_
|
||||
|
||||
#include "u_compiler.h"
|
||||
|
||||
typedef void (*mapi_proc)(void);
|
||||
|
||||
struct mapi_table;
|
||||
|
||||
PUBLIC void
|
||||
mapi_init(const char *spec);
|
||||
|
||||
PUBLIC mapi_proc
|
||||
mapi_get_proc_address(const char *name);
|
||||
|
||||
PUBLIC struct mapi_table *
|
||||
mapi_table_create(void);
|
||||
|
||||
PUBLIC void
|
||||
mapi_table_destroy(struct mapi_table *tbl);
|
||||
|
||||
PUBLIC void
|
||||
mapi_table_fill(struct mapi_table *tbl, const mapi_proc *procs);
|
||||
|
||||
PUBLIC void
|
||||
mapi_table_make_current(const struct mapi_table *tbl);
|
||||
|
||||
#endif /* _MAPI_H_ */
|
||||
402
src/mapi/mapi/mapi_abi.py
Normal file
402
src/mapi/mapi/mapi_abi.py
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Mesa 3-D graphics library
|
||||
# Version: 7.9
|
||||
#
|
||||
# Copyright (C) 2010 LunarG Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Authors:
|
||||
# Chia-I Wu <olv@lunarg.com>
|
||||
|
||||
import sys
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
# number of dynamic entries
|
||||
ABI_NUM_DYNAMIC_ENTRIES = 256
|
||||
|
||||
class ABIEntry(object):
|
||||
"""Represent an ABI entry."""
|
||||
|
||||
_match_c_param = re.compile(
|
||||
'^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
|
||||
|
||||
def __init__(self, cols, attrs):
|
||||
self._parse(cols)
|
||||
|
||||
self.slot = attrs['slot']
|
||||
self.hidden = attrs['hidden']
|
||||
self.alias = attrs['alias']
|
||||
|
||||
def c_prototype(self):
|
||||
return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
|
||||
|
||||
def c_return(self):
|
||||
ret = self.ret
|
||||
if not ret:
|
||||
ret = 'void'
|
||||
|
||||
return ret
|
||||
|
||||
def c_params(self):
|
||||
"""Return the parameter list used in the entry prototype."""
|
||||
c_params = []
|
||||
for t, n, a in self.params:
|
||||
sep = '' if t.endswith('*') else ' '
|
||||
arr = '[%d]' % a if a else ''
|
||||
c_params.append(t + sep + n + arr)
|
||||
if not c_params:
|
||||
c_params.append('void')
|
||||
|
||||
return ", ".join(c_params)
|
||||
|
||||
def c_args(self):
|
||||
"""Return the argument list used in the entry invocation."""
|
||||
c_args = []
|
||||
for t, n, a in self.params:
|
||||
c_args.append(n)
|
||||
|
||||
return ", ".join(c_args)
|
||||
|
||||
def _parse(self, cols):
|
||||
ret = cols.pop(0)
|
||||
if ret == 'void':
|
||||
ret = None
|
||||
|
||||
name = cols.pop(0)
|
||||
|
||||
params = []
|
||||
if not cols:
|
||||
raise Exception(cols)
|
||||
elif len(cols) == 1 and cols[0] == 'void':
|
||||
pass
|
||||
else:
|
||||
for val in cols:
|
||||
params.append(self._parse_param(val))
|
||||
|
||||
self.ret = ret
|
||||
self.name = name
|
||||
self.params = params
|
||||
|
||||
def _parse_param(self, c_param):
|
||||
m = self._match_c_param.match(c_param)
|
||||
if not m:
|
||||
raise Exception('unrecognized param ' + c_param)
|
||||
|
||||
c_type = m.group('type').strip()
|
||||
c_name = m.group('name')
|
||||
c_array = m.group('array')
|
||||
c_array = int(c_array) if c_array else 0
|
||||
|
||||
return (c_type, c_name, c_array)
|
||||
|
||||
def __str__(self):
|
||||
return self.c_prototype()
|
||||
|
||||
def __cmp__(self, other):
|
||||
# compare slot, alias, and then name
|
||||
res = cmp(self.slot, other.slot)
|
||||
if not res:
|
||||
if not self.alias:
|
||||
res = -1
|
||||
elif not other.alias:
|
||||
res = 1
|
||||
|
||||
if not res:
|
||||
res = cmp(self.name, other.name)
|
||||
|
||||
return res
|
||||
|
||||
def abi_parse_line(line):
|
||||
cols = [col.strip() for col in line.split(',')]
|
||||
|
||||
attrs = {
|
||||
'slot': -1,
|
||||
'hidden': False,
|
||||
'alias': None,
|
||||
}
|
||||
|
||||
# extract attributes from the first column
|
||||
vals = cols[0].split(':')
|
||||
while len(vals) > 1:
|
||||
val = vals.pop(0)
|
||||
if val.startswith('slot='):
|
||||
attrs['slot'] = int(val[5:])
|
||||
elif val == 'hidden':
|
||||
attrs['hidden'] = True
|
||||
elif val.startswith('alias='):
|
||||
attrs['alias'] = val[6:]
|
||||
elif not val:
|
||||
pass
|
||||
else:
|
||||
raise Exception('unknown attribute %s' % val)
|
||||
cols[0] = vals[0]
|
||||
|
||||
return (attrs, cols)
|
||||
|
||||
def abi_parse(filename):
|
||||
"""Parse a CSV file for ABI entries."""
|
||||
fp = open(filename) if filename != '-' else sys.stdin
|
||||
lines = [line.strip() for line in fp.readlines()
|
||||
if not line.startswith('#') and line.strip()]
|
||||
|
||||
entry_dict = {}
|
||||
next_slot = 0
|
||||
for line in lines:
|
||||
attrs, cols = abi_parse_line(line)
|
||||
|
||||
# post-process attributes
|
||||
if attrs['alias']:
|
||||
try:
|
||||
ent = entry_dict[attrs['alias']]
|
||||
slot = ent.slot
|
||||
except KeyError:
|
||||
raise Exception('failed to alias %s' % attrs['alias'])
|
||||
else:
|
||||
slot = next_slot
|
||||
next_slot += 1
|
||||
|
||||
if attrs['slot'] < 0:
|
||||
attrs['slot'] = slot
|
||||
elif attrs['slot'] != slot:
|
||||
raise Exception('invalid slot in %s' % (line))
|
||||
|
||||
ent = ABIEntry(cols, attrs)
|
||||
if entry_dict.has_key(ent.name):
|
||||
raise Exception('%s is duplicated' % (ent.name))
|
||||
entry_dict[ent.name] = ent
|
||||
|
||||
entries = entry_dict.values()
|
||||
entries.sort()
|
||||
|
||||
# sanity check
|
||||
i = 0
|
||||
for slot in xrange(next_slot):
|
||||
if entries[i].slot != slot:
|
||||
raise Exception('entries are not ordered by slots')
|
||||
if entries[i].alias:
|
||||
raise Exception('first entry of slot %d aliases %s'
|
||||
% (slot, entries[i].alias))
|
||||
while i < len(entries) and entries[i].slot == slot:
|
||||
i += 1
|
||||
if i < len(entries):
|
||||
raise Exception('there are %d invalid entries' % (len(entries) - 1))
|
||||
|
||||
return entries
|
||||
|
||||
def abi_dynamics():
|
||||
"""Return the dynamic entries."""
|
||||
entries = []
|
||||
for i in xrange(ABI_NUM_DYNAMIC_ENTRIES):
|
||||
cols = ['void', 'dynamic%d' % (i), 'void']
|
||||
attrs = { 'slot': -1, 'hidden': False, 'alias': None }
|
||||
entries.append(ABIEntry(cols, attrs))
|
||||
return entries
|
||||
|
||||
class ABIPrinter(object):
|
||||
"""ABIEntry Printer"""
|
||||
|
||||
def __init__(self, entries, options):
|
||||
self.entries = entries
|
||||
self.options = options
|
||||
self._undefs = []
|
||||
|
||||
def _add_undefs(self, undefs):
|
||||
self._undefs.extend(undefs)
|
||||
|
||||
def output_header(self):
|
||||
print '/* This file is automatically generated. Do not modify. */'
|
||||
print
|
||||
|
||||
def output_footer(self):
|
||||
print '/* clean up */'
|
||||
for m in self._undefs:
|
||||
print '#undef %s' % (m)
|
||||
|
||||
def output_entry(self, ent):
|
||||
if ent.slot < 0:
|
||||
out_ent = 'MAPI_DYNAMIC_ENTRY(%s, %s, (%s))' % \
|
||||
(ent.c_return(), ent.name, ent.c_params())
|
||||
out_code = ''
|
||||
else:
|
||||
if ent.alias:
|
||||
macro_ent = 'MAPI_ALIAS_ENTRY'
|
||||
macro_code = 'MAPI_ALIAS_CODE'
|
||||
else:
|
||||
macro_ent = 'MAPI_ABI_ENTRY'
|
||||
macro_code = 'MAPI_ABI_CODE'
|
||||
|
||||
if ent.ret:
|
||||
macro_code += '_RETURN'
|
||||
if ent.hidden:
|
||||
macro_ent += '_HIDDEN'
|
||||
macro_code += '_HIDDEN'
|
||||
|
||||
if ent.alias:
|
||||
out_ent = '%s(%s, %s, %s, (%s))' % (macro_ent,
|
||||
ent.alias, ent.c_return(), ent.name, ent.c_params())
|
||||
out_code = '%s(%s, %s, %s, (%s))' % (macro_code,
|
||||
ent.alias, ent.c_return(), ent.name, ent.c_args())
|
||||
else:
|
||||
out_ent = '%s(%s, %s, (%s))' % (macro_ent,
|
||||
ent.c_return(), ent.name, ent.c_params())
|
||||
out_code = '%s(%s, %s, (%s))' % (macro_code,
|
||||
ent.c_return(), ent.name, ent.c_args())
|
||||
|
||||
print out_ent
|
||||
if out_code:
|
||||
print ' ' + out_code
|
||||
|
||||
def output_entries(self, pool_offsets):
|
||||
defs = [
|
||||
# normal entries
|
||||
('MAPI_ABI_ENTRY', '(ret, name, params)', ''),
|
||||
('MAPI_ABI_CODE', '(ret, name, args)', ''),
|
||||
('MAPI_ABI_CODE_RETURN', '', 'MAPI_ABI_CODE'),
|
||||
# alias entries
|
||||
('MAPI_ALIAS_ENTRY', '(alias, ret, name, params)', ''),
|
||||
('MAPI_ALIAS_CODE', '(alias, ret, name, args)', ''),
|
||||
('MAPI_ALIAS_CODE_RETURN', '', 'MAPI_ALIAS_CODE'),
|
||||
# hidden normal entries
|
||||
('MAPI_ABI_ENTRY_HIDDEN', '', 'MAPI_ABI_ENTRY'),
|
||||
('MAPI_ABI_CODE_HIDDEN', '', 'MAPI_ABI_CODE'),
|
||||
('MAPI_ABI_CODE_RETURN_HIDDEN', '', 'MAPI_ABI_CODE_RETURN'),
|
||||
# hidden alias entries
|
||||
('MAPI_ALIAS_ENTRY_HIDDEN', '', 'MAPI_ALIAS_ENTRY'),
|
||||
('MAPI_ALIAS_CODE_HIDDEN', '', 'MAPI_ALIAS_CODE'),
|
||||
('MAPI_ALIAS_CODE_RETURN_HIDDEN', '', 'MAPI_ALIAS_CODE_RETURN'),
|
||||
# dynamic entries
|
||||
('MAPI_DYNAMIC_ENTRY', '(ret, name, params)', ''),
|
||||
]
|
||||
undefs = [d[0] for d in defs]
|
||||
|
||||
print '#if defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN)'
|
||||
print
|
||||
for d in defs:
|
||||
print '#ifndef %s' % (d[0])
|
||||
if d[2]:
|
||||
print '#define %s%s %s' % d
|
||||
else:
|
||||
print '#define %s%s' % d[:2]
|
||||
|
||||
print '#endif'
|
||||
print
|
||||
|
||||
print '/* see MAPI_TMP_TABLE */'
|
||||
for ent in self.entries:
|
||||
print '#define MAPI_SLOT_%s %d' % (ent.name, ent.slot)
|
||||
print
|
||||
print '/* see MAPI_TMP_PUBLIC_STUBS */'
|
||||
for ent in self.entries:
|
||||
print '#define MAPI_POOL_%s %d' % (ent.name, pool_offsets[ent])
|
||||
print
|
||||
|
||||
# define macros that generate code
|
||||
for ent in self.entries:
|
||||
self.output_entry(ent)
|
||||
print
|
||||
dynamics = abi_dynamics()
|
||||
for ent in dynamics:
|
||||
self.output_entry(ent)
|
||||
print
|
||||
|
||||
for ent in self.entries:
|
||||
print '#undef MAPI_SLOT_%s' % (ent.name)
|
||||
for ent in self.entries:
|
||||
print '#undef MAPI_POOL_%s' % (ent.name)
|
||||
print
|
||||
print '#endif /* defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN) */'
|
||||
print
|
||||
|
||||
self._add_undefs(undefs)
|
||||
|
||||
def _get_string_pool(self):
|
||||
"""Get the string pool."""
|
||||
pool = []
|
||||
offsets = {}
|
||||
|
||||
count = 0
|
||||
for ent in self.entries:
|
||||
offsets[ent] = count
|
||||
pool.append(ent.name + '\\0')
|
||||
count += len(ent.name) + 1
|
||||
|
||||
return (pool, offsets)
|
||||
|
||||
def output_sorted_indices(self):
|
||||
entry_index_pairs = []
|
||||
for i in xrange(len(self.entries)):
|
||||
entry_index_pairs.append((self.entries[i], i))
|
||||
entry_index_pairs.sort(lambda x, y: cmp(x[0].name, y[0].name))
|
||||
|
||||
print '/* see MAPI_TMP_PUBLIC_STUBS */'
|
||||
print '#ifdef MAPI_ABI_SORTED_INDICES'
|
||||
print
|
||||
print 'static const int MAPI_ABI_SORTED_INDICES[] = {'
|
||||
for ent, idx in entry_index_pairs:
|
||||
print ' %d, /* %s */' % (idx, ent.name)
|
||||
print ' -1'
|
||||
print '};'
|
||||
print
|
||||
print '#endif /* MAPI_ABI_SORTED_INDICES */'
|
||||
print
|
||||
|
||||
self._add_undefs(['MAPI_ABI_SORTED_INDICES'])
|
||||
|
||||
def output_defines(self):
|
||||
print '/* ABI defines */'
|
||||
print '#ifdef MAPI_ABI_DEFINES'
|
||||
print '#include "%s"' % (self.options.include)
|
||||
print '#endif /* MAPI_ABI_DEFINES */'
|
||||
print
|
||||
|
||||
self._add_undefs(['MAPI_ABI_DEFINES'])
|
||||
|
||||
def output(self):
|
||||
pool, pool_offsets = self._get_string_pool()
|
||||
|
||||
self.output_header()
|
||||
self.output_defines()
|
||||
self.output_entries(pool_offsets)
|
||||
self.output_sorted_indices()
|
||||
self.output_footer()
|
||||
|
||||
def parse_args():
|
||||
parser = OptionParser(usage='usage: %prog [options] <filename>')
|
||||
parser.add_option('-i', '--include', dest='include',
|
||||
help='include the header for API defines')
|
||||
|
||||
options, args = parser.parse_args()
|
||||
if not args or not options.include:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
return (args[0], options)
|
||||
|
||||
def main():
|
||||
filename, options = parse_args()
|
||||
|
||||
entries = abi_parse(filename)
|
||||
printer = ABIPrinter(entries, options)
|
||||
printer.output()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
186
src/mapi/mapi/mapi_tmp.h
Normal file
186
src/mapi/mapi/mapi_tmp.h
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include "u_macros.h"
|
||||
|
||||
#ifndef MAPI_ABI_HEADER
|
||||
#error "MAPI_ABI_HEADER must be defined"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Get API defines.
|
||||
*/
|
||||
#ifdef MAPI_TMP_DEFINES
|
||||
# define MAPI_ABI_DEFINES
|
||||
# include MAPI_ABI_HEADER
|
||||
|
||||
#ifndef MAPI_ABI_PREFIX
|
||||
#error "MAPI_ABI_PREFIX must be defined"
|
||||
#endif
|
||||
#ifndef MAPI_ABI_PUBLIC
|
||||
#error "MAPI_ABI_PUBLIC must be defined"
|
||||
#endif
|
||||
#ifndef MAPI_ABI_ATTR
|
||||
#error "MAPI_ABI_ATTR must be defined"
|
||||
#endif
|
||||
|
||||
#undef MAPI_TMP_DEFINES
|
||||
#endif /* MAPI_TMP_DEFINES */
|
||||
|
||||
|
||||
/**
|
||||
* Generate fields of struct mapi_table.
|
||||
*/
|
||||
#ifdef MAPI_TMP_TABLE
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
ret (MAPI_ABI_ATTR *name) params;
|
||||
# define MAPI_DYNAMIC_ENTRY(ret, name, params) \
|
||||
ret (MAPI_ABI_ATTR *name) params;
|
||||
# include MAPI_ABI_HEADER
|
||||
#undef MAPI_TMP_TABLE
|
||||
#endif /* MAPI_TMP_TABLE */
|
||||
|
||||
|
||||
/**
|
||||
* Declare public entries.
|
||||
*/
|
||||
#ifdef MAPI_TMP_PUBLIC_DECLARES
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
MAPI_ABI_PUBLIC ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
|
||||
# define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
|
||||
MAPI_ABI_ENTRY(ret, name, params);
|
||||
# define MAPI_ABI_ENTRY_HIDDEN(ret, name, params) \
|
||||
HIDDEN ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
|
||||
# define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params) \
|
||||
MAPI_ABI_ENTRY_HIDDEN(ret, name, params)
|
||||
# include MAPI_ABI_HEADER
|
||||
#undef MAPI_TMP_PUBLIC_DECLARES
|
||||
#endif /* MAPI_TMP_PUBLIC_DECLARES */
|
||||
|
||||
|
||||
/**
|
||||
* Generate string pool and public stubs.
|
||||
*/
|
||||
#ifdef MAPI_TMP_PUBLIC_STUBS
|
||||
/* define the string pool */
|
||||
static const char public_string_pool[] =
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
U_STRINGIFY(name) "\0"
|
||||
# define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
|
||||
MAPI_ABI_ENTRY(ret, name, params)
|
||||
# include MAPI_ABI_HEADER
|
||||
;
|
||||
/* define public_sorted_indices */
|
||||
# define MAPI_ABI_SORTED_INDICES public_sorted_indices
|
||||
# include MAPI_ABI_HEADER
|
||||
|
||||
/* define public_stubs */
|
||||
static const struct mapi_stub public_stubs[] = {
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
{ (mapi_func) U_CONCAT(MAPI_ABI_PREFIX, name), \
|
||||
MAPI_SLOT_ ## name, (void *) MAPI_POOL_ ## name },
|
||||
# define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
|
||||
MAPI_ABI_ENTRY(ret, name, params)
|
||||
# include MAPI_ABI_HEADER
|
||||
{ NULL, -1, (void *) -1 }
|
||||
};
|
||||
|
||||
#undef MAPI_TMP_PUBLIC_STUBS
|
||||
#endif /* MAPI_TMP_PUBLIC_STUBS */
|
||||
|
||||
|
||||
/**
|
||||
* Generate public entries.
|
||||
*/
|
||||
#ifdef MAPI_TMP_PUBLIC_ENTRIES
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params
|
||||
# define MAPI_ABI_CODE(ret, name, args) \
|
||||
{ \
|
||||
const struct mapi_table *tbl = u_current_get(); \
|
||||
tbl->name args; \
|
||||
}
|
||||
# define MAPI_ABI_CODE_RETURN(ret, name, args) \
|
||||
{ \
|
||||
const struct mapi_table *tbl = u_current_get(); \
|
||||
return tbl->name args; \
|
||||
}
|
||||
# define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
|
||||
MAPI_ABI_ENTRY(ret, name, params)
|
||||
# define MAPI_ALIAS_CODE(alias, ret, name, args) \
|
||||
MAPI_ABI_CODE(ret, alias, args)
|
||||
# define MAPI_ALIAS_CODE_RETURN(alias, ret, name, args) \
|
||||
MAPI_ABI_CODE_RETURN(ret, alias, args)
|
||||
# include MAPI_ABI_HEADER
|
||||
#undef MAPI_TMP_PUBLIC_ENTRIES
|
||||
#endif /* MAPI_TMP_PUBLIC_ENTRIES */
|
||||
|
||||
|
||||
/**
|
||||
* Generate noop entries.
|
||||
*/
|
||||
#ifdef MAPI_TMP_NOOP_ARRAY
|
||||
#ifdef DEBUG
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
static ret MAPI_ABI_ATTR U_CONCAT(noop_, name) params
|
||||
# define MAPI_ABI_CODE(ret, name, args) \
|
||||
{ \
|
||||
noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name)); \
|
||||
}
|
||||
# define MAPI_ABI_CODE_RETURN(ret, name, args) \
|
||||
{ \
|
||||
noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name)); \
|
||||
return (ret) 0; \
|
||||
}
|
||||
# include MAPI_ABI_HEADER
|
||||
|
||||
/* define the noop function array that may be casted to mapi_table */
|
||||
const mapi_func table_noop_array[] = {
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
(mapi_func) U_CONCAT(noop_, name),
|
||||
# define MAPI_DYNAMIC_ENTRY(ret, name, params) \
|
||||
(mapi_func) noop_generic,
|
||||
# include MAPI_ABI_HEADER
|
||||
(mapi_func) noop_generic
|
||||
};
|
||||
|
||||
#else /* DEBUG */
|
||||
|
||||
const mapi_func table_noop_array[] = {
|
||||
# define MAPI_ABI_ENTRY(ret, name, params) \
|
||||
(mapi_func) noop_generic,
|
||||
# define MAPI_DYNAMIC_ENTRY(ret, name, params) \
|
||||
(mapi_func) noop_generic,
|
||||
# include MAPI_ABI_HEADER
|
||||
(mapi_func) noop_generic
|
||||
};
|
||||
|
||||
#endif /* DEBUG */
|
||||
#undef MAPI_TMP_NOOP_ARRAY
|
||||
#endif /* MAPI_TMP_NOOP_ARRAY */
|
||||
|
|
@ -1,6 +1,19 @@
|
|||
# src/mapi/mapi/sources.mak
|
||||
#
|
||||
# When MAPI_GLAPI_CURRENT is defined, MAPI_GLAPI_SOURCES can be built without
|
||||
# MAPI_SOURCES and it is used by glapi.
|
||||
#
|
||||
# Otherwise, MAPI_ABI_HEADER must be defined. It should expand to the header
|
||||
# generated by mapi_abi.py.
|
||||
|
||||
MAPI_GLAPI_SOURCES = \
|
||||
u_current.c \
|
||||
u_execmem.c \
|
||||
u_thread.c
|
||||
|
||||
MAPI_SOURCES = \
|
||||
entry.c \
|
||||
mapi.c \
|
||||
stub.c \
|
||||
table.c \
|
||||
$(MAPI_GLAPI_SOURCES)
|
||||
|
|
|
|||
180
src/mapi/mapi/stub.c
Normal file
180
src/mapi/mapi/stub.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h> /* for offsetof */
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "u_current.h"
|
||||
#include "u_thread.h"
|
||||
#include "entry.h"
|
||||
#include "stub.h"
|
||||
#include "table.h"
|
||||
|
||||
#define MAPI_TABLE_FIRST_DYNAMIC \
|
||||
(offsetof(struct mapi_table, dynamic0) / sizeof(mapi_func))
|
||||
#define MAPI_TABLE_NUM_DYNAMIC \
|
||||
((offsetof(struct mapi_table, last) - \
|
||||
offsetof(struct mapi_table, dynamic0)) / sizeof(mapi_func))
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
* This will define public_string_pool, public_sorted_indices, and
|
||||
* public_stubs.
|
||||
*/
|
||||
#define MAPI_TMP_PUBLIC_STUBS
|
||||
#include "mapi_tmp.h"
|
||||
|
||||
static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
|
||||
static int num_dynamic_stubs;
|
||||
static int next_dynamic_slot = MAPI_TABLE_FIRST_DYNAMIC;
|
||||
|
||||
void
|
||||
stub_init_once(void)
|
||||
{
|
||||
#ifdef PTHREADS
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&once, entry_patch_public);
|
||||
#else
|
||||
static int first = 1;
|
||||
if (first) {
|
||||
first = 0;
|
||||
entry_patch_public();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
stub_compare(const void *key, const void *elem)
|
||||
{
|
||||
const char *name = (const char *) key;
|
||||
const int *index = (const int *) elem;
|
||||
const struct mapi_stub *stub;
|
||||
const char *stub_name;
|
||||
|
||||
stub = &public_stubs[*index];
|
||||
stub_name = &public_string_pool[(unsigned long) stub->name];
|
||||
|
||||
return strcmp(name, stub_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the public stub with the given name.
|
||||
*/
|
||||
const struct mapi_stub *
|
||||
stub_find_public(const char *name)
|
||||
{
|
||||
const int *index;
|
||||
|
||||
index = (const int *) bsearch(name, public_sorted_indices,
|
||||
ARRAY_SIZE(public_sorted_indices) - 1,
|
||||
sizeof(public_sorted_indices[0]), stub_compare);
|
||||
|
||||
return (index) ? &public_stubs[*index] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a dynamic stub.
|
||||
*/
|
||||
static struct mapi_stub *
|
||||
stub_add_dynamic(const char *name)
|
||||
{
|
||||
struct mapi_stub *stub;
|
||||
int idx;
|
||||
|
||||
idx = num_dynamic_stubs;
|
||||
if (idx >= MAPI_TABLE_NUM_DYNAMIC)
|
||||
return NULL;
|
||||
|
||||
stub = &dynamic_stubs[idx];
|
||||
|
||||
/* dispatch to mapi_table->last, which is always no-op */
|
||||
stub->addr =
|
||||
entry_generate(MAPI_TABLE_FIRST_DYNAMIC + MAPI_TABLE_NUM_DYNAMIC);
|
||||
if (!stub->addr)
|
||||
return NULL;
|
||||
|
||||
stub->name = (const void *) name;
|
||||
/* to be fixed later */
|
||||
stub->slot = -1;
|
||||
|
||||
num_dynamic_stubs = idx + 1;
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dynamic stub with the given name. If no such stub exists and
|
||||
* generate is true, a new stub is generated.
|
||||
*/
|
||||
struct mapi_stub *
|
||||
stub_find_dynamic(const char *name, int generate)
|
||||
{
|
||||
u_mutex_declare_static(dynamic_mutex);
|
||||
struct mapi_stub *stub = NULL;
|
||||
int count, i;
|
||||
|
||||
u_mutex_lock(dynamic_mutex);
|
||||
|
||||
if (generate)
|
||||
assert(!stub_find_public(name));
|
||||
|
||||
count = num_dynamic_stubs;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (strcmp(name, (const char *) dynamic_stubs[i].name) == 0) {
|
||||
stub = &dynamic_stubs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a dynamic stub */
|
||||
if (generate && !stub)
|
||||
stub = stub_add_dynamic(name);
|
||||
|
||||
u_mutex_unlock(dynamic_mutex);
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
||||
void
|
||||
stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if (stub->slot >= 0)
|
||||
return;
|
||||
|
||||
if (alias)
|
||||
slot = alias->slot;
|
||||
else
|
||||
slot = next_dynamic_slot++;
|
||||
|
||||
entry_patch(stub->addr, slot);
|
||||
stub->slot = slot;
|
||||
}
|
||||
52
src/mapi/mapi/stub.h
Normal file
52
src/mapi/mapi/stub.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#ifndef _STUB_H_
|
||||
#define _STUB_H_
|
||||
|
||||
typedef void (*mapi_func)(void);
|
||||
|
||||
struct mapi_stub {
|
||||
mapi_func addr;
|
||||
int slot;
|
||||
const void *name;
|
||||
};
|
||||
|
||||
void
|
||||
stub_init_once(void);
|
||||
|
||||
const struct mapi_stub *
|
||||
stub_find_public(const char *name);
|
||||
|
||||
struct mapi_stub *
|
||||
stub_find_dynamic(const char *name, int generate);
|
||||
|
||||
void
|
||||
stub_fix_dynamic(struct mapi_stub *stub, const struct mapi_stub *alias);
|
||||
|
||||
#endif /* _STUB_H_ */
|
||||
56
src/mapi/mapi/table.c
Normal file
56
src/mapi/mapi/table.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stub.h"
|
||||
#include "table.h"
|
||||
|
||||
static void
|
||||
noop_warn(const char *name)
|
||||
{
|
||||
static int debug = -1;
|
||||
|
||||
if (debug < 0)
|
||||
debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"));
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "%s is no-op", name);
|
||||
}
|
||||
|
||||
static int
|
||||
noop_generic(void)
|
||||
{
|
||||
noop_warn("function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* define noop_array */
|
||||
#define MAPI_TMP_NOOP_ARRAY
|
||||
#include "mapi_tmp.h"
|
||||
76
src/mapi/mapi/table.h
Normal file
76
src/mapi/mapi/table.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#ifndef _TABLE_H_
|
||||
#define _TABLE_H_
|
||||
|
||||
#include "u_compiler.h"
|
||||
#include "stub.h"
|
||||
|
||||
#define MAPI_TMP_DEFINES
|
||||
#include "mapi_tmp.h"
|
||||
|
||||
struct mapi_table {
|
||||
#define MAPI_TMP_TABLE
|
||||
#include "mapi_tmp.h"
|
||||
mapi_func last;
|
||||
};
|
||||
|
||||
extern const mapi_func table_noop_array[];
|
||||
|
||||
/**
|
||||
* Get the no-op dispatch table.
|
||||
*/
|
||||
static INLINE const struct mapi_table *
|
||||
table_get_noop(void)
|
||||
{
|
||||
return (const struct mapi_table *) table_noop_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the dispatch table to dispatch a stub to the given function.
|
||||
*/
|
||||
static INLINE void
|
||||
table_set_func(struct mapi_table *tbl,
|
||||
const struct mapi_stub *stub, mapi_func func)
|
||||
{
|
||||
mapi_func *funcs = (mapi_func *) tbl;
|
||||
funcs[stub->slot] = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dispatched function of a stub.
|
||||
*/
|
||||
static INLINE mapi_func
|
||||
table_get_func(const struct mapi_table *tbl, const struct mapi_stub *stub)
|
||||
{
|
||||
const mapi_func *funcs = (const mapi_func *) tbl;
|
||||
return funcs[stub->slot];
|
||||
}
|
||||
|
||||
#endif /* _TABLE_H_ */
|
||||
12
src/mapi/mapi/u_macros.h
Normal file
12
src/mapi/mapi/u_macros.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _U_MACROS_
|
||||
#define _U_MACROS_
|
||||
|
||||
#define _U_STRINGIFY(x) #x
|
||||
#define _U_CONCAT(x, y) x ## y
|
||||
#define _U_CONCAT_STR(x, y) #x#y
|
||||
|
||||
#define U_STRINGIFY(x) _U_STRINGIFY(x)
|
||||
#define U_CONCAT(x, y) _U_CONCAT(x, y)
|
||||
#define U_CONCAT_STR(x, y) _U_CONCAT_STR(x, y)
|
||||
|
||||
#endif /* _U_MACROS_ */
|
||||
Loading…
Add table
Reference in a new issue