commit 959e3cf982e564cd5f4791fe3205faeda805935f
parent dcc97bed52d6218d8d4a4cdb40dd3238b8b9071e
Author: William Casarin <jb55@jb55.com>
Date: Thu, 21 Dec 2017 06:17:20 -0800
OP_DUP: copy vals
otherwise it only copies as reference, which is not what we want and is really
bad
Diffstat:
6 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/alloc.c b/alloc.c
@@ -26,7 +26,7 @@ alloc_arena_sizes(struct arenas *arenas, const int nums, const int bytes) {
}
struct num *
-num_pool_get(const int ind) {
+num_pool_get(const u16 ind) {
return &g_arenas.nums[ind];
}
@@ -39,7 +39,7 @@ num_pool_pop() {
struct num *
-num_pool_new(int *ind) {
+num_pool_new(u16 *ind) {
*ind = g_arenas.num_count++;
struct num *p;
p = &g_arenas.nums[*ind];
diff --git a/alloc.h b/alloc.h
@@ -10,9 +10,9 @@
#define MAX_PUSHDATA_REFS (MAX_OPS_PER_SCRIPT * MAX_STACK_SIZE)
#define ALLOC_PUSHDATA_BYTES (MAX_STACK_SIZE * MAX_OPS_PER_SCRIPT)
-struct num * num_pool_new(int *ind);
+struct num * num_pool_new(u16 *ind);
struct num * num_pool_pop();
-struct num * num_pool_get(const int ind);
+struct num * num_pool_get(const u16 ind);
u8 *byte_pool_new(u32 len, u16 *ind);
u8 *byte_pool_get(int ind, u32 *len);
diff --git a/script.c b/script.c
@@ -288,8 +288,8 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
SCRIPTERR("INVALID_STACK_OPERATION");
struct val v1 = stack_top_val(stack, -2);
struct val v2 = stack_top_val(stack, -1);
- stack_push_val(stack, v1);
- stack_push_val(stack, v2);
+ stack_push_val(stack, val_copy(v1));
+ stack_push_val(stack, val_copy(v2));
}
break;
@@ -301,9 +301,9 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
struct val v1 = stack_top_val(stack, -3);
struct val v2 = stack_top_val(stack, -2);
struct val v3 = stack_top_val(stack, -1);
- stack_push_val(stack, v1);
- stack_push_val(stack, v2);
- stack_push_val(stack, v3);
+ stack_push_val(stack, val_copy(v1));
+ stack_push_val(stack, val_copy(v2));
+ stack_push_val(stack, val_copy(v3));
}
break;
@@ -387,7 +387,7 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
if (stack_size(stack) < 1)
SCRIPTERR("INVALID_STACK_OPERATION");
struct val val = stack_top_val(stack, (-1));
- stack_push_val(stack, val);
+ stack_push_val(stack, val_copy(val));
}
break;
@@ -532,7 +532,7 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
// (in -- out)
if (stack_size(stack) < 1)
SCRIPTERR("INVALID_STACK_OPERATION");
- struct num *bn;
+ struct num *bn;
enum sn_result res =
sn_from_val(stack_top_val(stack, -1), &bn, require_minimal);
diff --git a/script_num.c b/script_num.c
@@ -101,7 +101,7 @@ int_from_data(u8 *data, u16 size) {
enum sn_result
sn_from_data(u8 *data, u16 size, struct num **num) {
- int ind;
+ u16 ind;
s64 i;
i = int_from_data(data, size);
if (int_overflowed(i)) {
@@ -157,7 +157,7 @@ struct val
sn_to_val(struct num *sn) {
struct val val;
struct num *snref;
- int ind;
+ u16 ind;
if (sn_overflowed(sn)) {
u16 ind, len;
diff --git a/val.c b/val.c
@@ -18,7 +18,7 @@ struct val
val_from_int(s64 intval) {
struct val val;
struct num *sn;
- int ind;
+ u16 ind;
sn = num_pool_new(&ind);
val.type = VT_SCRIPTNUM;
val.ind = ind;
@@ -133,6 +133,31 @@ val_eq(struct val a, struct val b, int require_minimal) {
return eq;
}
+struct val
+val_copy(struct val a) {
+ u32 len;
+ u16 newind;
+ u8 *src, *dst;
+ struct num *nsrc, *ndst;
+
+ switch (a.type) {
+ case VT_SMALLINT:
+ return a;
+ case VT_DATA:
+ src = byte_pool_get(a.ind, &len);
+ dst = byte_pool_new(len, &newind);
+ memcpy(dst, src, len);
+ a.ind = newind;
+ return a;
+ case VT_SCRIPTNUM:
+ nsrc = num_pool_get(a.ind);
+ ndst = num_pool_new(&newind);
+ ndst->val = nsrc->val;
+ return sn_to_val(ndst);
+ default:
+ assert(!"unhandle val_copy enum");
+ }
+}
/* struct val */
/* val_int(s64 n) { */
diff --git a/val.h b/val.h
@@ -31,6 +31,7 @@ struct val {
// we want val to fit into the size of a 32-bit pointer
STATIC_ASSERT(sizeof(struct val) <= 4, val_doesnt_fit_in_stack);
+struct val val_copy(struct val a);
int
val_eq(struct val a, struct val b, int require_minimal);