[pure-lang-svn] SF.net SVN: pure-lang:[777] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-09-17 15:26:10
|
Revision: 777 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=777&view=rev Author: agraef Date: 2008-09-17 15:05:12 +0000 (Wed, 17 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-17 08:32:48 UTC (rev 776) +++ pure/trunk/interpreter.cc 2008-09-17 15:05:12 UTC (rev 777) @@ -5033,10 +5033,7 @@ us[i] = act_env().CreateCall(module->getFunction("pure_matrix_columns"), vs); } - if (n == 1) - return us[1]; - else - return act_env().CreateCall(module->getFunction("pure_matrix_rows"), us); + return act_env().CreateCall(module->getFunction("pure_matrix_rows"), us); } // application: case EXPR::APP: Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-17 08:32:48 UTC (rev 776) +++ pure/trunk/runtime.cc 2008-09-17 15:05:12 UTC (rev 777) @@ -686,11 +686,19 @@ double_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { gsl_matrix *mat = gsl_matrix_alloc(nrows, ncols); - if (!mat) return 0; // XXXTODO: empty matrices + if (!mat) { + // XXXTODO: empty matrices + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + return 0; + } double *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { pure_expr *x = xs[count]; + pure_new_internal(x); switch (x->tag) { case EXPR::INT: data[i++*tda] = (double)x->data.i; @@ -720,8 +728,9 @@ assert(0 && "bad matrix element"); break; } - pure_freenew(x); } + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); return pure_double_matrix(mat); } @@ -729,11 +738,19 @@ double_matrix_columns(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { gsl_matrix *mat = gsl_matrix_alloc(nrows, ncols); - if (!mat) return 0; // XXXTODO: empty matrices + if (!mat) { + // XXXTODO: empty matrices + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + return 0; + } double *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { pure_expr *x = xs[count]; + pure_new_internal(x); switch (x->tag) { case EXPR::INT: data[i++] = (double)x->data.i; @@ -747,8 +764,9 @@ case EXPR::MATRIX: { gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p; if (mat1) - for (size_t j = 0; j < mat1->size1; i++, j++) - memcpy(data+j*tda+i, mat1->data+j*mat1->tda, ncols*sizeof(double)); + for (size_t j = 0; j < mat1->size1; j++) + memcpy(data+j*tda+i, mat1->data+j*mat1->tda, + mat1->size2*sizeof(double)); i += mat1->size2; break; } @@ -765,8 +783,9 @@ assert(0 && "bad matrix element"); break; } - pure_freenew(x); } + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); return pure_double_matrix(mat); } @@ -774,11 +793,19 @@ int_matrix_rows(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { gsl_matrix_int *mat = gsl_matrix_int_alloc(nrows, ncols); - if (!mat) return 0; // XXXTODO: empty matrices + if (!mat) { + // XXXTODO: empty matrices + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + return 0; + } int *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { pure_expr *x = xs[count]; + pure_new_internal(x); switch (x->tag) { case EXPR::INT: data[i++*tda] = x->data.i; @@ -808,8 +835,9 @@ assert(0 && "bad matrix element"); break; } - pure_freenew(x); } + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); return pure_int_matrix(mat); } @@ -817,11 +845,19 @@ int_matrix_columns(size_t nrows, size_t ncols, size_t n, pure_expr **xs) { gsl_matrix_int *mat = gsl_matrix_int_alloc(nrows, ncols); - if (!mat) return 0; // XXXTODO: empty matrices + if (!mat) { + // XXXTODO: empty matrices + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + return 0; + } int *data = mat->data; size_t tda = mat->tda; for (size_t count = 0, i = 0; count < n; count++) { pure_expr *x = xs[count]; + pure_new_internal(x); switch (x->tag) { case EXPR::INT: data[i++] = x->data.i; @@ -844,8 +880,9 @@ case EXPR::IMATRIX: { gsl_matrix *mat1 = (gsl_matrix*)x->data.mat.p; if (mat1) - for (size_t j = 0; j < mat1->size1; i++, j++) - memcpy(data+j*tda+i, mat1->data+j*mat1->tda, ncols*sizeof(int)); + for (size_t j = 0; j < mat1->size1; j++) + memcpy(data+j*tda+i, mat1->data+j*mat1->tda, + mat1->size2*sizeof(int)); i += mat1->size2; break; } @@ -853,8 +890,9 @@ assert(0 && "bad matrix element"); break; } - pure_freenew(x); } + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); return pure_int_matrix(mat); } #endif @@ -1762,21 +1800,25 @@ { #ifdef HAVE_GSL va_list ap; - va_start(ap, n); pure_expr **xs = (pure_expr**)alloca(n*sizeof(pure_expr*)); - size_t m = 0; int k = -1; + int k = -1; size_t nrows = 0, ncols = 0; int32_t target = EXPR::IMATRIX; + bool have_matrix = false; + pure_expr *x = 0, *ret = 0; + va_start(ap, n); + for (size_t i = 0; i < n; i++) + xs[i] = va_arg(ap, pure_expr*); + va_end(ap); for (size_t i = 0; i < n; i++) { - pure_expr *x = va_arg(ap, pure_expr*); + x = xs[i]; switch (x->tag) { case EXPR::DBL: if (target == EXPR::IMATRIX) target = EXPR::MATRIX; case EXPR::INT: case EXPR::BIGINT: - if (k >= 0 && k != 1) pure_throw(bad_matrix_exception(x)); - xs[m++] = x; nrows++; - k = 1; + if (k >= 0 && k != 1) goto err; + nrows++; k = 1; break; case EXPR::APP: { pure_expr *u = x->data.x[0], *v = x->data.x[1]; @@ -1788,87 +1830,93 @@ if ((!rect || f->tag != rect->f) && (!polar || f->tag != polar->f) && f->tag != interp.symtab.pair_sym().f) - pure_throw(bad_matrix_exception(x)); + goto err; u = u->data.x[1]; if (u->tag != EXPR::INT && u->tag != EXPR::BIGINT && u->tag != EXPR::DBL) - pure_throw(bad_matrix_exception(x)); + goto err; if (v->tag != EXPR::INT && v->tag != EXPR::BIGINT && v->tag != EXPR::DBL) - pure_throw(bad_matrix_exception(x)); + goto err; } else - pure_throw(bad_matrix_exception(x)); - if (k >= 0 && k != 1) pure_throw(bad_matrix_exception(x)); + goto err; + if (k >= 0 && k != 1) goto err; target = EXPR::CMATRIX; - xs[m++] = x; nrows++; - k = 1; + nrows++; k = 1; break; } case EXPR::MATRIX: { gsl_matrix *mp = (gsl_matrix*)x->data.mat.p; if (mp) { if (k >= 0 && mp->size2 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size1 > 0) xs[m++] = x; - nrows += mp->size1; - k = mp->size2; + goto err; + nrows += mp->size1; k = mp->size2; } else if (k>0) - pure_throw(bad_matrix_exception(x)); + goto err; if (target == EXPR::IMATRIX) target = EXPR::MATRIX; + have_matrix = true; break; } case EXPR::CMATRIX: { gsl_matrix_complex *mp = (gsl_matrix_complex*)x->data.mat.p; if (mp) { if (k >= 0 && mp->size2 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size1 > 0) xs[m++] = x; - nrows += mp->size1; - k = mp->size2; + goto err; + nrows += mp->size1; k = mp->size2; } else if (k>0) - pure_throw(bad_matrix_exception(x)); + goto err; target = EXPR::CMATRIX; + have_matrix = true; break; } case EXPR::IMATRIX: { gsl_matrix_int *mp = (gsl_matrix_int*)x->data.mat.p; if (mp) { if (k >= 0 && mp->size2 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size1 > 0) xs[m++] = x; - nrows += mp->size1; - k = mp->size2; + goto err; + nrows += mp->size1; k = mp->size2; } else if (k>0) - pure_throw(bad_matrix_exception(x)); + goto err; + have_matrix = true; break; } default: - pure_throw(bad_matrix_exception(x)); + goto err; break; } } - va_end(ap); + if (n == 1 && have_matrix) return xs[0]; if (k < 0) k = 0; ncols = k; if (nrows == 0 && ncols == 0) target = EXPR::MATRIX; - pure_expr *ret = 0; switch (target) { case EXPR::MATRIX: - ret = double_matrix_rows(nrows, ncols, m, xs); + ret = double_matrix_rows(nrows, ncols, n, xs); break; #if 0 // XXXTODO case EXPR::CMATRIX: - ret = complex_matrix_rows(nrows, ncols, m, xs); + ret = complex_matrix_rows(nrows, ncols, n, xs); break; #endif case EXPR::IMATRIX: - ret = int_matrix_rows(nrows, ncols, m, xs); + ret = int_matrix_rows(nrows, ncols, n, xs); break; default: break; } if (!ret) pure_throw(not_implemented_exception()); return ret; + err: + /* This is called without a shadow stack frame, so we do our own cleanup + here to avoid having temporaries hanging around indefinitely. */ + if (x) x->refc++; + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + pure_unref_internal(x); + pure_throw(bad_matrix_exception(x)); + return 0; #else pure_throw(not_implemented_exception()); return 0; @@ -1880,21 +1928,25 @@ { #ifdef HAVE_GSL va_list ap; - va_start(ap, n); pure_expr **xs = (pure_expr**)alloca(n*sizeof(pure_expr*)); - size_t m = 0; int k = -1; + int k = -1; size_t nrows = 0, ncols = 0; int32_t target = EXPR::IMATRIX; + bool have_matrix = false; + pure_expr *x = 0, *ret = 0; + va_start(ap, n); + for (size_t i = 0; i < n; i++) + xs[i] = va_arg(ap, pure_expr*); + va_end(ap); for (size_t i = 0; i < n; i++) { - pure_expr *x = va_arg(ap, pure_expr*); + x = xs[i]; switch (x->tag) { case EXPR::DBL: if (target == EXPR::IMATRIX) target = EXPR::MATRIX; case EXPR::INT: case EXPR::BIGINT: - if (k >= 0 && k != 1) pure_throw(bad_matrix_exception(x)); - xs[m++] = x; ncols++; - k = 1; + if (k >= 0 && k != 1) goto err; + ncols++; k = 1; break; case EXPR::APP: { pure_expr *u = x->data.x[0], *v = x->data.x[1]; @@ -1906,87 +1958,93 @@ if ((!rect || f->tag != rect->f) && (!polar || f->tag != polar->f) && f->tag != interp.symtab.pair_sym().f) - pure_throw(bad_matrix_exception(x)); + goto err; u = u->data.x[1]; if (u->tag != EXPR::INT && u->tag != EXPR::BIGINT && u->tag != EXPR::DBL) - pure_throw(bad_matrix_exception(x)); + goto err; if (v->tag != EXPR::INT && v->tag != EXPR::BIGINT && v->tag != EXPR::DBL) - pure_throw(bad_matrix_exception(x)); + goto err; } else - pure_throw(bad_matrix_exception(x)); - if (k >= 0 && k != 1) pure_throw(bad_matrix_exception(x)); + goto err; + if (k >= 0 && k != 1) goto err; target = EXPR::CMATRIX; - xs[m++] = x; ncols++; - k = 1; + ncols++; k = 1; break; } case EXPR::MATRIX: { gsl_matrix *mp = (gsl_matrix*)x->data.mat.p; if (mp) { if (k >= 0 && mp->size1 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size2 > 0) xs[m++] = x; - ncols += mp->size2; - k = mp->size1; + goto err; + ncols += mp->size2; k = mp->size1; } else if (k>0) - pure_throw(bad_matrix_exception(x)); + goto err; if (target == EXPR::IMATRIX) target = EXPR::MATRIX; + have_matrix = true; break; } case EXPR::CMATRIX: { gsl_matrix_complex *mp = (gsl_matrix_complex*)x->data.mat.p; if (mp) { if (k >= 0 && mp->size1 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size2 > 0) xs[m++] = x; - ncols += mp->size2; - k = mp->size1; + goto err; + ncols += mp->size2; k = mp->size1; } else if (k>0) - pure_throw(bad_matrix_exception(x)); + goto err; + target = EXPR::CMATRIX; + have_matrix = true; break; } case EXPR::IMATRIX: { gsl_matrix_int *mp = (gsl_matrix_int*)x->data.mat.p; if (mp) { - if (k >= 0 && mp->size2 != (size_t)k) - pure_throw(bad_matrix_exception(x)); - if (mp->size1 > 0) xs[m++] = x; - ncols += mp->size2; - k = mp->size2; + if (k >= 0 && mp->size1 != (size_t)k) + goto err; + ncols += mp->size2; k = mp->size1; } else if (k>0) - pure_throw(bad_matrix_exception(x)); - target = EXPR::CMATRIX; + goto err; + have_matrix = true; break; } default: - pure_throw(bad_matrix_exception(x)); + goto err; break; } } - va_end(ap); + if (n == 1 && have_matrix) return xs[0]; if (k < 0) k = 0; nrows = k; if (nrows == 0 && ncols == 0) target = EXPR::MATRIX; - pure_expr *ret = 0; switch (target) { case EXPR::MATRIX: - ret = double_matrix_columns(nrows, ncols, m, xs); + ret = double_matrix_columns(nrows, ncols, n, xs); break; #if 0 // XXXTODO case EXPR::CMATRIX: - ret = complex_matrix_columns(nrows, ncols, m, xs); + ret = complex_matrix_columns(nrows, ncols, n, xs); break; #endif case EXPR::IMATRIX: - ret = int_matrix_columns(nrows, ncols, m, xs); + ret = int_matrix_columns(nrows, ncols, n, xs); break; default: break; } if (!ret) pure_throw(not_implemented_exception()); return ret; + err: + /* This is called without a shadow stack frame, so we do our own cleanup + here to avoid having temporaries hanging around indefinitely. */ + if (x) x->refc++; + for (size_t i = 0; i < n; i++) + pure_new_internal(xs[i]); + for (size_t i = 0; i < n; i++) + pure_free_internal(xs[i]); + pure_unref_internal(x); + pure_throw(bad_matrix_exception(x)); + return 0; #else pure_throw(not_implemented_exception()); return 0; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-09-17 08:32:48 UTC (rev 776) +++ pure/trunk/runtime.h 2008-09-17 15:05:12 UTC (rev 777) @@ -148,9 +148,11 @@ list of element expressions, which can be component matrices or scalars. The pure_matrix_rows functions arrange the elements vertically, while the pure_matrix_columns functions arrange them horizontally, given that the - other dimensions match. The elems vectors are owned by the caller and won't - be freed. A null expression is returned in case of an error (no matrix - support, dimension mismatch, or invalid element type). */ + other dimensions match. A null expression is returned in case of an error + (no matrix support, dimension mismatch, or invalid element type). Otherwise + a new matrix expression is returned. Temporary element expressions are + taken over by the callee and will be garbage-collected, but the elems + vectors are owned by the caller and won't be freed. */ pure_expr *pure_matrix_rowsl(uint32_t n, ...); pure_expr *pure_matrix_rowsv(uint32_t n, pure_expr **elems); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |