mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-24 04:25:06 +02:00
Fix load_varargs to prevent local var corruption
Assigning to a varargs variable that is not passed by the C caller can result in corruption of another parameter. EG: the var contains data for another parameter, which is then changed unexpectedly. The code was rewritten to assign to a new variable, to prevent this from happening.
This commit is contained in:
parent
5855c77a74
commit
4230295683
2 changed files with 23 additions and 22 deletions
6
cgen.scm
6
cgen.scm
|
@ -878,7 +878,7 @@
|
||||||
((pair? (cdr formals))
|
((pair? (cdr formals))
|
||||||
(string-append ", " (c-compile-formals (cdr formals) type)))
|
(string-append ", " (c-compile-formals (cdr formals) type)))
|
||||||
((not (equal? 'args:fixed type))
|
((not (equal? 'args:fixed type))
|
||||||
(string-append ", object " (mangle (cdr formals)) ", ..."))
|
(string-append ", object " (mangle (cdr formals)) "_raw, ..."))
|
||||||
(else
|
(else
|
||||||
"")))))
|
"")))))
|
||||||
|
|
||||||
|
@ -925,7 +925,9 @@
|
||||||
; (number->string (length (lambda-formals->list exp))) ");"
|
; (number->string (length (lambda-formals->list exp))) ");"
|
||||||
"load_varargs("
|
"load_varargs("
|
||||||
(mangle (lambda-varargs-var exp))
|
(mangle (lambda-varargs-var exp))
|
||||||
", argc - " (number->string
|
", "
|
||||||
|
(mangle (lambda-varargs-var exp))
|
||||||
|
"_raw, argc - " (number->string
|
||||||
(- (length (lambda-formals->list exp))
|
(- (length (lambda-formals->list exp))
|
||||||
1
|
1
|
||||||
(if has-closure? 1 0)))
|
(if has-closure? 1 0)))
|
||||||
|
|
39
runtime.h
39
runtime.h
|
@ -37,28 +37,27 @@ static object cell_get(object cell){
|
||||||
our compiler will compute the difference between the number of required
|
our compiler will compute the difference between the number of required
|
||||||
args and the number of provided ones, and pass the difference as 'count'
|
args and the number of provided ones, and pass the difference as 'count'
|
||||||
*/
|
*/
|
||||||
#define load_varargs(var, count) { \
|
#define load_varargs(var, arg_var, count) \
|
||||||
int i; \
|
list var = (count > 0) ? alloca(sizeof(cons_type)*count) : nil; \
|
||||||
object tmp; \
|
{ \
|
||||||
list args = nil; \
|
int i; \
|
||||||
va_list va; \
|
object tmp; \
|
||||||
if (count > 0) { \
|
va_list va; \
|
||||||
args = alloca(sizeof(cons_type)*count); \
|
if (count > 0) { \
|
||||||
va_start(va, var); \
|
va_start(va, arg_var); \
|
||||||
for (i = 0; i < count; i++) { \
|
for (i = 0; i < count; i++) { \
|
||||||
if (i) { \
|
if (i) { \
|
||||||
tmp = va_arg(va, object); \
|
tmp = va_arg(va, object); \
|
||||||
} else { \
|
} else { \
|
||||||
tmp = var; \
|
tmp = arg_var; \
|
||||||
|
} \
|
||||||
|
var[i].tag = cons_tag; \
|
||||||
|
var[i].cons_car = tmp; \
|
||||||
|
var[i].cons_cdr = (i == (count-1)) ? nil : &var[i + 1]; \
|
||||||
} \
|
} \
|
||||||
args[i].tag = cons_tag; \
|
va_end(va); \
|
||||||
args[i].cons_car = tmp; \
|
|
||||||
args[i].cons_cdr = (i == (count-1)) ? nil : &args[i + 1]; \
|
|
||||||
} \
|
} \
|
||||||
va_end(va); \
|
}
|
||||||
} \
|
|
||||||
var = args; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prototypes for Lisp built-in functions. */
|
/* Prototypes for Lisp built-in functions. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue