summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-03-23 06:08:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-03-23 06:08:45 -0700
commit3d27521df2a8174eb470a30ce6c4fd84b7d61464 (patch)
tree27a05115ae6469a11b7ed6bdc8e362ac5a07484f
parent2a8b1e4388daa00005cbc1e25913479075507ab2 (diff)
downloadtxr-3d27521df2a8174eb470a30ce6c4fd84b7d61464.tar.gz
txr-3d27521df2a8174eb470a30ce6c4fd84b7d61464.tar.bz2
txr-3d27521df2a8174eb470a30ce6c4fd84b7d61464.zip
umethod: use new dynamic args to avoid consing list.
* args.c (args_cat): New function. * args.h (args_cat): Declared. * struct.c (umethod_args_fun): env parameter is now a dynamic args object. Code adjusted accordingly. (umethod): Duplicate the args into a dynamic args object instead of consing up a list and also eliminate the temporary cons since we can pass the additional argument using the car field of the dynamic args.
-rw-r--r--args.c9
-rw-r--r--args.h1
-rw-r--r--struct.c15
3 files changed, 18 insertions, 7 deletions
diff --git a/args.c b/args.c
index 22c9fadd..cb8c062b 100644
--- a/args.c
+++ b/args.c
@@ -97,6 +97,15 @@ struct args *args_copy_zap(struct args *to, struct args *from)
return to;
}
+struct args *args_cat(struct args *to, struct args *from)
+{
+ size_t size = sizeof *from->arg * from->fill;
+ to->list = from->list;
+ memcpy(to->arg + to->fill, from->arg, size);
+ to->fill += from->fill;
+ return to;
+}
+
struct args *args_cat_zap(struct args *to, struct args *from)
{
size_t size = sizeof *from->arg * from->fill;
diff --git a/args.h b/args.h
index 13296ac8..c1455fd6 100644
--- a/args.h
+++ b/args.h
@@ -181,6 +181,7 @@ INLINE cnum args_count(struct args *args)
val args_get_checked(val name, struct args *args, cnum *arg_index);
struct args *args_copy(struct args *to, struct args *from);
struct args *args_copy_zap(struct args *to, struct args *from);
+struct args *args_cat(struct args *to, struct args *from);
struct args *args_cat_zap(struct args *to, struct args *from);
struct args *args_cat_zap_from(struct args *to, struct args *from, cnum index);
struct args *args_copy_reverse(struct args *to, struct args *from, cnum nargs);
diff --git a/struct.c b/struct.c
index f411762a..f0ceb3d6 100644
--- a/struct.c
+++ b/struct.c
@@ -1607,22 +1607,23 @@ static val umethod_fun(val sym, struct args *args)
}
}
-static val umethod_args_fun(val env, struct args *args)
+static val umethod_args_fun(val dargs, struct args *args)
{
val self = lit("umethod");
- cons_bind (sym, curried_args, env);
+ val sym = dargs->a.car;
+ struct args *da = dargs->a.args;
if (!args_more(args, 0)) {
uw_throwf(error_s, lit("~a: object argument required to call ~s"),
self, env, nao);
} else {
- cnum ca_len = c_num(length(curried_args));
+ cnum da_nargs = da->fill + c_num(length(da->list));
cnum index = 0;
val strct = args_get(args, &index);
- args_decl(args_call, max(args->fill + ca_len, ARGS_MIN));
+ args_decl(args_call, max(args->fill + da_nargs, ARGS_MIN));
args_add(args_call, strct);
- args_add_list(args_call, curried_args);
- args_normalize_exact(args_call, ca_len + 1);
+ args_cat(args_call, da);
+ args_normalize_exact(args_call, da_nargs + 1);
args_cat_zap_from(args_call, args, index);
struct struct_inst *si = struct_handle_for_slot(strct, self, sym);
@@ -1642,7 +1643,7 @@ val umethod(val slot, struct args *args)
if (!args_more(args, 0))
return func_f0v(slot, umethod_fun);
else
- return func_f0v(cons(slot, args_get_list(args)), umethod_args_fun);
+ return func_f0v(dyn_args(args, slot, nil), umethod_args_fun);
}
static void struct_inst_print(val obj, val out, val pretty,