better handling of NULL in printf, and varargs
This commit is contained in:
Родитель
5f3a9ffd0e
Коммит
e4f6c3cba2
|
@ -1933,7 +1933,7 @@ function JSify(data) {
|
|||
return makePointer(JSON.stringify(makeEmptyStruct(type)));
|
||||
} else if (value.text[0] == '"') {
|
||||
value.text = value.text.substr(1, value.text.length-2);
|
||||
return makePointer(JSON.stringify(parseLLVMString(value.text)));
|
||||
return makePointer(JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text + '*/');
|
||||
} else {
|
||||
// Gets an array of constant items, separated by ',' tokens
|
||||
function handleSegments(tokens) {
|
||||
|
@ -2062,8 +2062,6 @@ function JSify(data) {
|
|||
|
||||
func.splitItems -= lines.length;
|
||||
if (func.splitItems === 0) {
|
||||
postJSOptimize(func);
|
||||
|
||||
// Final recombination
|
||||
//print('zz params::::: ' + JSON.stringify(func.params));
|
||||
//print('zz params::::: ' + JSON.stringify(parseParamTokens(func.params.item[0].tokens)));
|
||||
|
@ -2075,11 +2073,15 @@ function JSify(data) {
|
|||
return null;
|
||||
}
|
||||
return toNiceIdent(param.ident);
|
||||
}).filter(function(param) { return param != null }).join(', ');
|
||||
}).filter(function(param) { return param != null });;
|
||||
|
||||
func.JS = '\nfunction ' + func.ident + '(' + params + ') {\n';
|
||||
func.JS = '\nfunction ' + func.ident + '(' + params.join(', ') + ') {\n';
|
||||
if (LABEL_DEBUG) func.JS += " print(INDENT + ' Entering: " + func.ident + "'); INDENT += ' ';\n";
|
||||
|
||||
if (hasVarArgs) {
|
||||
func.JS += ' __numArgs__ = ' + params.length + ';\n';
|
||||
}
|
||||
|
||||
// Walk function blocks and generate JS
|
||||
function walkBlock(block, indent) {
|
||||
if (!block) return '';
|
||||
|
@ -2136,11 +2138,6 @@ function JSify(data) {
|
|||
return ret;
|
||||
},
|
||||
});
|
||||
function postJSOptimize(func) {
|
||||
// Some optimizations are easier to apply after JS-ing the code - for example, a lot
|
||||
// of stuff can end up as x = y; for example, bitcasts, or nativized, etc. If we
|
||||
// we to optimize pre-JS, we would need to be aware of all of that.
|
||||
}
|
||||
|
||||
function getVarData(funcData, ident) {
|
||||
if (funcData.variables[ident]) {
|
||||
|
@ -2448,14 +2445,12 @@ function JSify(data) {
|
|||
return ident;
|
||||
});
|
||||
function makeFunctionCall(ident, params) {
|
||||
//print('// zz makeFC: ' + ident + ' : ' + dump(params));
|
||||
|
||||
// Special cases
|
||||
if (ident == '_llvm_va_start') {
|
||||
if (SAFE_HEAP) {
|
||||
return 'SAFE_HEAP_STORE(' + params[0].ident + ', Pointer_make(Array.prototype.slice.call(arguments, 1).concat([0]), 0))';
|
||||
return 'SAFE_HEAP_STORE(' + params[0].ident + ', Pointer_make(Array.prototype.slice.call(arguments, __numArgs__).concat([0]), 0))';
|
||||
} else {
|
||||
return 'HEAP[' + params[0].ident + '] = Pointer_make(Array.prototype.slice.call(arguments, 1).concat([0]), 0)'; // XXX 1
|
||||
return 'HEAP[' + params[0].ident + '] = Pointer_make(Array.prototype.slice.call(arguments, __numArgs__).concat([0]), 0)';
|
||||
}
|
||||
} else if (ident == '_llvm_va_end') {
|
||||
return ';'
|
||||
|
|
|
@ -8,8 +8,8 @@ var __THREW__ = false; // Used in checking for thrown exceptions.
|
|||
|
||||
var __ATEXIT__ = [];
|
||||
|
||||
var HEAP = [0];
|
||||
var HEAPTOP = 1; // Leave 0 as an invalid address, 'NULL'
|
||||
var HEAP = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
|
||||
var HEAPTOP = HEAP.length+1; // Leave 0 as an invalid address, 'NULL'
|
||||
|
||||
#if SAFE_HEAP
|
||||
// Semi-manual memory corruption debugging
|
||||
|
|
|
@ -234,11 +234,11 @@ class T(unittest.TestCase):
|
|||
printf("%d", atoi(argv[3])+2);
|
||||
const char *foolingthecompiler = "\\rabcd";
|
||||
printf("%d", strlen(foolingthecompiler)); // Tests parsing /0D in llvm - should not be a 0 (end string) then a D!
|
||||
printf("%s*", NULL); // Should print nothing, not the string at address 0, which is a real address for us!
|
||||
printf("%s*", NULL); // Should print '(null)', not the string at address 0, which is a real address for us!
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
self.do_test(src, '*4*wowie*too*76*5**', ['wowie', 'too', '74'], lambda x: x.replace('\n', '*'))
|
||||
self.do_test(src, '*4*wowie*too*76*5*(null)*', ['wowie', 'too', '74'], lambda x: x.replace('\n', '*'))
|
||||
|
||||
def test_funcs(self):
|
||||
src = '''
|
||||
|
@ -613,12 +613,24 @@ class T(unittest.TestCase):
|
|||
va_end(v);
|
||||
}
|
||||
|
||||
void vary2(char color, const char *s, ...)
|
||||
{
|
||||
va_list v;
|
||||
va_start(v, s);
|
||||
char d[21];
|
||||
d[0] = color;
|
||||
vsnprintf(d+1, 20, s, v);
|
||||
puts(d);
|
||||
va_end(v);
|
||||
}
|
||||
|
||||
int main() {
|
||||
vary("*cheez: %d+%d*", 10, 24);
|
||||
vary2('Q', "%d*", 85);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
self.do_test(src, '*cheez: 10+24*')
|
||||
self.do_test(src, '*cheez: 10+24*\nQ85*')
|
||||
|
||||
def test_atexit(self):
|
||||
src = '''
|
||||
|
|
Загрузка…
Ссылка в новой задаче