Conflicts:
	.project
	COPYRIGHT
	Doc/Manual/style.css
	Examples/Makefile.in
	Examples/test-suite/common.mk
	Lib/typemaps/strings.swg
	Makefile.in
	Source/DOH/fio.c
	Source/Makefile.am
	Source/Modules/emit.cxx
	Source/Modules/javascript.cxx
	configure.in

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13764 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Oliver Buchtala 2012-09-08 00:56:48 +00:00
commit 050219d998
136 changed files with 7987 additions and 141 deletions

View file

@ -0,0 +1,217 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#include <dlfcn.h>
#include <JavaScriptCore/JavaScript.h>
using namespace std;
static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex);
static char* jsccreateStringWithContentsOfFile(const char* fileName);
bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* FunctionName,JSObjectCallAsFunctionCallback cbFunction);
typedef void* HANDLE;
typedef int (*JSCIntializer)(JSGlobalContextRef context);
void jsc_printError(JSContextRef, JSValueRef, const std::string&);
void print_usage() {
std::cout << "javascript [-l module] <js-file>" << std::endl;
}
int main(int argc, char* argv[]) {
std::string scriptPath;
std::vector<std::string> module_names;
std::vector<HANDLE> loaded_modules;
std::vector<JSCIntializer> module_initializers;
for (int idx = 1; idx < argc; ++idx) {
if(strcmp(argv[idx], "-l") == 0) {
idx++;
if(idx > argc) {
print_usage();
exit(-1);
}
std::string module_name(argv[idx]);
module_names.push_back(module_name);
} else {
scriptPath = argv[idx];
}
}
for(std::vector<std::string>::iterator it = module_names.begin();
it != module_names.end(); ++it) {
std::string module_name = *it;
std::string lib_name = std::string("lib").append(module_name).append(".so");
HANDLE handle = dlopen(lib_name.c_str(), RTLD_LAZY);
if(handle == 0) {
std::cout << "Could not load library " << lib_name << ":"
<< std::endl << dlerror() << std::endl;
continue;
}
std::string symname;
symname.append(module_name).append("_initialize");
JSCIntializer init_function = reinterpret_cast<JSCIntializer>((long) dlsym(handle, symname.c_str()));
if(init_function == 0) {
std::cout << "Could not find initializer function in module " << module_name << std::endl;
dlclose(handle);
continue;
}
loaded_modules.push_back(handle);
module_initializers.push_back(init_function);
}
static int failed;
JSGlobalContextRef context = JSGlobalContextCreate(NULL);
JSObjectRef globalObject = JSContextGetGlobalObject(context);
jsc_registerFunction(context, globalObject, "print", jsc_printstring); // Utility print function
// Call module initializers
for(std::vector<JSCIntializer>::iterator it = module_initializers.begin();
it != module_initializers.end(); ++it) {
JSCIntializer init_function = *it;
init_function(context);
}
// Evaluate the javascript
char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str());
JSStringRef jsScript;
if(!scriptContent) {
printf("FAIL: runme script could not be loaded.\n");
failed = 1;
}
else {
JSValueRef ex;
jsScript = JSStringCreateWithUTF8CString(scriptContent);
JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex);
if (!jsResult && ex) {
jsc_printError(context, ex, scriptPath);
failed = 1;
}
}
if (scriptContent != NULL) {
free(scriptContent);
}
JSStringRelease(jsScript);
JSGlobalContextRelease(context);
globalObject = 0;
for(std::vector<HANDLE>::iterator it = loaded_modules.begin();
it != loaded_modules.end(); ++it) {
HANDLE handle = *it;
dlclose(handle);
}
if (failed) {
printf("FAIL: Some tests failed.\n");
return 1;
}
}
static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex)
{
if (argc > 0)
{
JSStringRef string = JSValueToStringCopy(context, args[0], NULL);
size_t numChars = JSStringGetMaximumUTF8CStringSize(string);
char *stringUTF8 = new char[numChars];
JSStringGetUTF8CString(string, stringUTF8, numChars);
printf("%s\n", stringUTF8);
delete[] stringUTF8;
}
return JSValueMakeUndefined(context);
}
static char* jsccreateStringWithContentsOfFile(const char* fileName)
{
char* buffer;
size_t buffer_size = 0;
size_t buffer_capacity = 1024;
buffer = (char*)malloc(buffer_capacity);
FILE* f = fopen(fileName, "r");
if (!f)
{
fprintf(stderr, "Could not open file: %s\n", fileName);
return 0;
}
while (!feof(f) && !ferror(f))
{
buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
if (buffer_size == buffer_capacity)
{
// guarantees space for trailing '\0'
buffer_capacity *= 2;
buffer = (char*)realloc(buffer, buffer_capacity);
}
}
fclose(f);
buffer[buffer_size] = '\0';
return buffer;
}
bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object,
const char* functionName, JSObjectCallAsFunctionCallback callback)
{
JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName);
JSObjectSetProperty(context, object, js_functionName,
JSObjectMakeFunctionWithCallback(context, js_functionName, callback),
kJSPropertyAttributeNone, NULL);
JSStringRelease(js_functionName);
return true;
}
void jsc_printError(JSContextRef ctx, JSValueRef err, const std::string& sourceUrl)
{
char *buffer;
JSStringRef string = JSValueToStringCopy(ctx, err, 0);
size_t length = JSStringGetLength(string);
buffer = (char*) malloc(length+1);
JSStringGetUTF8CString(string, buffer, length+1);
std::string errMsg(buffer);
JSStringRelease(string);
free(buffer);
JSObjectRef errObj = JSValueToObject(ctx, err, 0);
if(errObj == 0) {
return;
}
// Note: usually you would also retrieve the property "sourceURL"
// though, it happened that this was always ""
JSStringRef lineKey = JSStringCreateWithUTF8CString("line");
JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0);
int line = (int) JSValueToNumber(ctx, jsLine, 0);
JSStringRelease(lineKey);
std::cerr << sourceUrl << ":" << line << ":" << errMsg << std::endl;
}

24
Tools/swigprinters.gdb Normal file
View file

@ -0,0 +1,24 @@
python
import sys
import os
try:
global SWIG_PRINTER_DIR
sys.path.insert(0, SWIG_PRINTER_DIR)
except NameError:
raise RuntimeError("""
---------------------------------------------------------
Change ~/.gdbinit to be able to use swig pretty printers:
> set python SWIG_PRINTER_DIR = <path/to/swig>/Tools
> source <path/to/swig>/Tools/swigprinters.gdb
---------------------------------------------------------
""")
from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \
setChildrenRecursionLevel
#enableGdbPrintWorkaround()
#setChildrenRecursionLevel(2)
register_swig_printers (None)
end

574
Tools/swigprinters.py Executable file
View file

@ -0,0 +1,574 @@
import gdb
import gdb.types
import itertools
import re
log_file = None
GDB_FLATTENED_CHILDREN_WORKAROUND = False
CHILDREN_MAX_RECURSION_LEVEL = 0
# workaround: don't cast the following DOHs to it's actual type
# to avoid infinite pretty-print loops
cast_black_list = {
'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling'])
}
def print_(msg):
global log_file;
if True:
if log_file == None:
log_file = open('swig_gdb.log', 'w')
log_file.write(msg)
print(msg)
class SwigStringPrinter:
"""
Pretty print Swig String* types.
"""
def __init__ (self, typename, val):
self.typename = typename
self.val = val
try:
self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer()
self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
except Exception as err:
print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err)))
def display_hint(self):
return 'string'
def to_string(self):
ret = "<invalid>"
# Conversion taken from Swig Internals manual:
# http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7
# (*(struct String *)(((DohBase *)s)->data)).str
dohbase = None;
str_data = None;
char_ptr = None;
try:
dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference()
except Exception as err:
print_("SwigStringPrinter: Could not dereference DOHBase*\n");
return "<invalid>";
try:
str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference()
except Exception as err:
print_("SwigStringPrinter: Could not dereference struct String*\n");
return "<invalid>";
try:
char_ptr = str_data['str']
except Exception as err:
print_("SwigStringPrinter: Could not access field (struct String).str\n");
return "<invalid>";
if char_ptr.is_lazy is True:
char_ptr.fetch_lazy ()
try:
ret = char_ptr.string()
except Exception as err:
print_("SwigStringPrinter: Could not convert const char* to string\n");
return "<invalid>";
return ret
class SwigIterator:
def __init__(self):
self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
self.t_string_ptr = gdb.lookup_type("String").pointer()
self.t_node_ptr = gdb.lookup_type("Node").pointer()
self.t_hash_ptr = gdb.lookup_type("Hash").pointer()
self.t_file_ptr = gdb.lookup_type("File").pointer()
self.t_void_ptr = gdb.lookup_type("void").pointer()
def cast_doh(self, doh, name = None):
if doh == 0:
return doh
doh = doh.reinterpret_cast(self.t_doh_base_ptr);
val_base = doh.dereference()
val_type = val_base['type'].dereference()
val_typestr = val_type['objname'].string()
if not name == None and val_typestr in cast_black_list:
blacklist = cast_black_list[val_typestr]
if name in blacklist:
return doh
if "String" == val_typestr:
doh = doh.reinterpret_cast(self.t_string_ptr)
elif "File" == val_typestr:
doh = doh.reinterpret_cast(self.t_file_ptr)
# BUG: GDB Pyhton can not handle cyclic references yet
# so these casts are deactivated
elif "Hash" == val_typestr:
doh = doh.reinterpret_cast(self.t_hash_ptr)
elif "Node" == val_typestr:
doh = doh.reinterpret_cast(self.t_node_ptr)
return doh
class SwigListIterator(SwigIterator):
def __init__(self, val):
SwigIterator.__init__(self);
try:
self.valid = False
self.val = val.reinterpret_cast(self.t_doh_base_ptr)
val_base = self.val.dereference()
val_type = val_base['type'].dereference()
val_typestr = val_type['objname'].string()
#print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr)
self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer()
doh_base = self.val.dereference()
self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference()
self.address = 0
self._index = 0
self.key = 0
self.item = 0
self.address = self.val.dereference().address
self.is_first = True
self.valid = True
except Exception as err:
print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err)))
def __iter__(self):
return self
def List_first(self):
self.object = None;
self._index = 0
self.key = 0
self.nitems = int(self.l['nitems'])
self.items = self.l['items']
if self.nitems > 0:
self.item = self.items[0]
else:
self.stop()
def List_next(self):
self._index = self._index + 1
if self._index >= self.nitems:
self.stop()
else:
self.item = self.items[self._index]
def next(self):
if not self.valid:
self.stop()
if self.is_first:
self.is_first = False
try:
self.List_first()
except StopIteration:
raise StopIteration
except Exception as err:
print_("Error during iteration to first node: \n %s \n" %(str(err)))
self.stop()
else:
try:
self.List_next()
except StopIteration:
raise StopIteration
except Exception as err:
print_("Error during iteration to first node: \n %s \n" %(str(err)))
self.stop()
key_str = "[%d]"%self._index
item = 0
try:
item = self.cast_doh(self.item)
except Exception as err:
print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) )
self.stop()
return (key_str, item)
def stop(self):
self.is_first = True
self.item = 0
self.key = 0
raise StopIteration
class SwigHashIterator(SwigIterator):
def __init__(self, val):
SwigIterator.__init__(self);
try:
self.valid = False
self.val = val.reinterpret_cast(self.t_doh_base_ptr)
self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer()
self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer()
doh_base = self.val.dereference()
hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference()
self.hashtable = hash_['hashtable']
self.hashsize = int(hash_['hashsize'])
self.nitems = int(hash_['nitems'])
self.next_ = 0
self.address = 0
self.pos = 0;
self._current = 0
self.item = 0
self.key = 0
self._index = 0
self.address = self.val.dereference().address
self.is_first = True
self.valid = True
except Exception as err:
print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err)))
def __iter__(self):
return self
def Hash_firstiter(self):
self._current = 0;
self.item = 0;
self.key = 0;
self._index = 0;
while (self._index < self.hashsize) and (self.hashtable[self._index] == 0):
self._index = self._index+1;
if self._index >= self.hashsize:
self.stop();
self._current = self.hashtable[self._index]
self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr);
self.item = self._current['object'];
self.key = self._current['key'];
self._current = self._current['next'];
def Hash_nextiter(self):
if self._current == 0:
self._index = self._index + 1
while (self._index < self.hashsize) and (self.hashtable[self._index] == 0):
self._index = self._index + 1
if self._index >= self.hashsize:
self.item = 0;
self.key = 0;
self._current = 0;
self.stop()
self._current = self.hashtable[self._index];
self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr);
self.key = self._current['key'];
self.item = self._current['object'];
self._current = self._current['next'];
def next(self):
if not self.valid:
self.stop()
if self.is_first:
self.is_first = False
try:
self.Hash_firstiter()
except StopIteration:
raise StopIteration
except Exception as err:
print_("Error during iteration to first node: \n %s \n" %(str(err)))
self.stop()
else:
try:
self.Hash_nextiter()
except StopIteration:
raise StopIteration
except Exception as err:
print_("Error during iteration to first node: \n %s \n" %(str(err)))
self.stop()
key_str = "<err>"
item = 0
try:
string_printer = SwigStringPrinter("String *", self.key)
key_str = string_printer.to_string()
except Exception as err:
print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) )
self.stop()
try:
item = self.cast_doh(self.item, key_str)
except Exception as err:
print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) )
self.stop()
return (key_str, item)
def stop(self):
self.is_first = True
raise StopIteration
class AlternateKeyValueIterator():
def __init__(self, iterable):
self.it = iterable.__iter__()
self._next = None
self.count = -1
def __iter__(self):
return self
def next(self):
if self._next == None:
key, value = self.it.next()
self._next = value
self.count = self.count + 1
return ("[%d]"%self.count, key)
else:
value = self._next
self._next = None
return ("[%d]"%self.count, value)
class NopIterator:
def __init__(self):
pass
def __iter__(self):
return self
def next(self):
raise StopIteration
class SwigListPrinter:
"""
Pretty print Swig List* types (also ParmList*).
"""
def __init__ (self, typename, val):
self.typename = typename
self.val = val
it = SwigListIterator(val)
self.valid = it.valid
self.address = it.address
def display_hint(self):
return 'array'
def to_string(self):
return "%s(%s)" % (str(self.typename), str(self.address))
def children(self):
if not self.valid:
print_("SwigListPrinter: Invalid state.\n")
return NopIterator()
try:
it = SwigListIterator(self.val)
return it
except Exception as err:
print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err)))
raise err
class SwigHashPrinter:
"""
Pretty print Swig Hash* types (also Node*).
"""
def __init__ (self, typename, val):
self.typename = typename
self.val = val
it = SwigHashIterator(val)
self.valid = it.valid
self.address = it.address
self.level = 0;
def display_hint(self):
return 'map'
def to_string(self):
return "%s(%s)" % (str(self.typename), str(self.address))
def children(self):
global GDB_FLATTENED_CHILDREN_WORKAROUND
global CHILDREN_MAX_RECURSION_LEVEL
if not self.valid:
print_("SwigHashPrinter: Invalid state.\n")
return NopIterator()
if self.level > CHILDREN_MAX_RECURSION_LEVEL:
return NopIterator()
try:
it = SwigHashIterator(self.val)
if GDB_FLATTENED_CHILDREN_WORKAROUND:
return AlternateKeyValueIterator(it)
return it
except Exception as err:
print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err)))
raise err
class SwigSimplePrinter:
def __init__ (self, typename, val):
self.typename = typename
self.val = val
def display_hint(self):
return "string"
def to_string(self):
return "%s(%s)"%(self.typename, str(self.val.address))
class SwigDelegatingPrinter:
def __init__ (self, typename, val):
t_doh_base_ptr = gdb.lookup_type("DohBase").pointer()
val_base = val.reinterpret_cast(t_doh_base_ptr).dereference()
val_type = val_base['type'].dereference()
val_typestr = val_type['objname'].string()
self.has_children = False
if val_typestr == "Hash":
self.delegate = SwigHashPrinter(typename, val)
self.has_children = True
elif val_typestr == "List":
self.delegate = SwigListPrinter(typename, val)
self.has_children = True
elif val_typestr == "String":
self.delegate = SwigStringPrinter(typename, val)
else:
self.delegate = SwigSimplePrinter(typename, val)
def display_hint(self):
return self.delegate.display_hint()
def to_string(self):
return self.delegate.to_string()
def children(self):
if not self.has_children:
return NopIterator()
return self.delegate.children()
class RxPrinter(object):
def __init__(self, name, function):
super(RxPrinter, self).__init__()
self.name = name
self.function = function
self.enabled = True
def invoke(self, value):
if not self.enabled:
return None
return self.function(self.name, value)
# A pretty-printer that conforms to the "PrettyPrinter" protocol from
# gdb.printing. It can also be used directly as an old-style printer.
class Printer(object):
def __init__(self, name):
super(Printer, self).__init__()
self.name = name
self.subprinters = []
self.lookup = {}
self.enabled = True
self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$')
def add(self, name, function):
if not self.compiled_rx.match(name):
raise ValueError, 'error: "%s" does not match' % name
printer = RxPrinter(name, function)
self.subprinters.append(printer)
self.lookup[name] = printer
print('Added pretty printer for %s. ' % (name))
def __call__(self, val):
typename = str(val.type)
if typename in self.lookup:
ret = self.lookup[typename].invoke(val)
return ret
# Cannot find a pretty printer. Return None.
return None
swig_printer = None
def register_swig_printers(obj):
global swig_printer
if obj is None:
obj = gdb
obj.pretty_printers.append(swig_printer)
def build_swig_printer():
global swig_printer
swig_printer = Printer("swig")
swig_printer.add('String *', SwigStringPrinter)
swig_printer.add('const String *', SwigStringPrinter)
swig_printer.add('SwigType *', SwigStringPrinter)
swig_printer.add('Hash *', SwigHashPrinter)
swig_printer.add('const Hash *', SwigHashPrinter)
swig_printer.add('Node *', SwigHashPrinter)
swig_printer.add('const Node *', SwigHashPrinter)
swig_printer.add('Parm *', SwigHashPrinter)
swig_printer.add('const Parm *', SwigHashPrinter)
swig_printer.add('List *', SwigListPrinter)
swig_printer.add('const List *', SwigListPrinter)
swig_printer.add('ParmList *', SwigDelegatingPrinter)
swig_printer.add('const ParmList *', SwigDelegatingPrinter)
swig_printer.add('File *', SwigDelegatingPrinter)
#swig_printer.add('DOH *', SwigDelegatingPrinter)
#swig_printer.add('const DOH *', SwigDelegatingPrinter)
print_("Loaded swig printers\n");
def enableGdbPrintWorkaround():
global GDB_FLATTENED_CHILDREN_WORKAROUND
GDB_FLATTENED_CHILDREN_WORKAROUND = True
def setChildrenRecursionLevel(level):
global CHILDREN_MAX_RECURSION_LEVEL
CHILDREN_MAX_RECURSION_LEVEL = level
build_swig_printer()