commit 4ec313b99db973af87e88c6421fb4fb228531341
parent 8cb4e6f3311178f0099f637ac1e2eb69a92987d1
Author: William Casarin <jb55@jb55.com>
Date: Mon, 3 Jun 2019 12:12:42 -0700
fixup val/stack distinction
Diffstat:
7 files changed, 91 insertions(+), 50 deletions(-)
diff --git a/main.c b/main.c
@@ -51,7 +51,7 @@ int main(int argc, const char *argv[]) {
/* size = g_reader_buf_top - g_reader_buf; */
printf("script ");
script_print_vals(&g_reader_stack);
- script_serialize_minimal(&g_reader_stack, buf, bufsize, &compiled_len);
+ script_serialize(&g_reader_stack, buf, bufsize, &compiled_len);
script_eval(buf, compiled_len, &tmp_stack, &result);
printf("script_hex ");
@@ -61,7 +61,7 @@ int main(int argc, const char *argv[]) {
printf("output ");
script_print_vals(&tmp_stack);
- script_serialize(&tmp_stack, buf, bufsize, &compiled_len);
+ stack_serialize(&tmp_stack, buf, bufsize, &compiled_len);
printf("output_hex ");
for(i = 0; i < compiled_len; ++i)
diff --git a/script.c b/script.c
@@ -801,8 +801,7 @@ script_push_raw(struct stack *stack, const char *data) {
script_push_datastr(stack, data, 1);
}
-void script_serialize_(struct stack *stack, u8 *buf, int buflen,
- int* len, int serialize_minimal)
+void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len)
{
struct val *valp;
void **sp;
@@ -815,25 +814,64 @@ void script_serialize_(struct stack *stack, u8 *buf, int buflen,
/* printf("%02x %02x %02x %02x | ", huh[0], huh[1], huh[2], huh[3]); */
/* printf("%d %d\n", val.type, val.ind); */
valp = (struct val*)sp;
- val_serialize(*valp, &valsize, p, buflen-(p-buf),
- serialize_minimal);
+
+ if (valp->type == VT_SCRIPTNUM) {
+ struct num *sn = num_pool_get(valp->ind);
+
+ if (sn->val == -1) {
+ valsize = 1;
+ *p = OP_1NEGATE;
+ }
+ else if (sn->val == 0 ) {
+ valsize = 1;
+ *p = 0;
+ }
+ else if (sn->val >= 1 && sn->val <= 16 ) {
+ valsize = 1;
+ *p = OP_1 - 1 + sn->val;
+ }
+ else {
+ val_serialize(*valp, &valsize, p+1, buflen-((p+1)-buf));
+ assert(valsize <= 0xFF);
+ *p = (u8)valsize;
+ valsize++;
+ }
+ }
+ else {
+ val_serialize(*valp, &valsize, p, buflen-(p-buf));
+ }
+
+
p += valsize;
*len += valsize;
assert(p-buf <= buflen);
sp++;
}
-}
-void
-script_handle_input(struct stack *stack, const char *str) {
}
-void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len)
-{
- script_serialize_(stack, buf, buflen, len, 0);
+void stack_serialize(struct stack *stack, u8 *buf, int buflen, int *len) {
+ struct val *valp;
+ void **sp;
+ u8 *p = buf;
+ u32 valsize;
+ *len = 0;
+ sp = stack->bottom;
+
+ while (sp < stack->top) {
+ /* printf("%02x %02x %02x %02x | ", huh[0], huh[1], huh[2], huh[3]); */
+ /* printf("%d %d\n", val.type, val.ind); */
+ valp = (struct val*)sp;
+
+ val_serialize(*valp, &valsize, p, buflen-(p-buf));
+
+ p += valsize;
+ *len += valsize;
+ assert(p-buf <= buflen);
+ sp++;
+ }
}
-void script_serialize_minimal(struct stack *stack, u8 *buf, int buflen, int* len)
-{
- script_serialize_(stack, buf, buflen, len, 1);
+void
+script_handle_input(struct stack *stack, const char *str) {
}
diff --git a/script.h b/script.h
@@ -22,7 +22,7 @@ void script_push_raw(struct stack *, const char *str);
void script_push_datastr(struct stack *, const char *str, int israw);
void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len);
-void script_serialize_minimal(struct stack *stack, u8 *buf, int buflen, int* len);
+void stack_serialize(struct stack *stack, u8 *buf, int buflen, int* len);
extern int g_silence_script_err;
extern int g_silence_script_warn;
diff --git a/script_num.c b/script_num.c
@@ -31,8 +31,7 @@ sn_from_int(s64 n, struct num *sn) {
/* } */
-void
-sn_serialize(struct num *sn, u8 *buf, int bufsize, u16 *len) {
+void sn_serialize(struct num *sn, u8 *buf, int bufsize, u16 *len) {
u8 *p = buf;
if(sn->val == 0) {
@@ -44,7 +43,7 @@ sn_serialize(struct num *sn, u8 *buf, int bufsize, u16 *len) {
u64 absvalue = neg ? -(sn->val) : sn->val;
while(absvalue) {
- *p++ = absvalue & 0xff;
+ *(p++) = absvalue & 0xff;
assert((p - buf) <= bufsize);
absvalue >>= 8;
}
@@ -60,7 +59,7 @@ sn_serialize(struct num *sn, u8 *buf, int bufsize, u16 *len) {
// converting to an integral.
if (*(p - 1) & 0x80)
- *p++ = neg ? 0x80 : 0;
+ *(p++) = neg ? 0x80 : 0;
else if (neg)
*(p - 1) |= 0x80;
diff --git a/test.c b/test.c
@@ -95,20 +95,21 @@ TEST(test_2dup_not_enough_input) {
TEST(negative_integer) {
static u8 buf[6];
- int len;
- u8 in_script[] = { 0x01, 0x82 };
- int res = script_eval(in_script, ARRAY_SIZE(in_script), stack, result);
- script_serialize(stack, buf, ARRAY_SIZE(buf), &len);
- cmp_data(buf, in_script, len, ARRAY_SIZE(in_script), "negative 2 serializes ok");
+ int buflen;
+ u8 expected_in[] = { 0x01, 0x82 };
+ u8 expected_out[] = { 0x82 };
+ script_eval(expected_in, sizeof(expected_in), stack, result);
+ stack_serialize(stack, buf, sizeof(buf), &buflen);
+ cmp_data(buf, expected_out, buflen, sizeof(expected_out), "negative 2 serializes ok");
}
TEST(add_negative_two) {
static u8 buf[12];
int len;
static u8 in_script[] = { 0x01, 0x82, 0x01, 0x82, OP_ADD };
- static u8 expected_out[] = { 0x01, 0x84 };
- int res = script_eval(in_script, ARRAY_SIZE(in_script), stack, result);
- script_serialize(stack, buf, ARRAY_SIZE(buf), &len);
+ static u8 expected_out[] = { 0x84 };
+ script_eval(in_script, ARRAY_SIZE(in_script), stack, result);
+ stack_serialize(stack, buf, sizeof(buf), &len);
cmp_data(buf, expected_out, len, ARRAY_SIZE(expected_out), "add negative two twice");
}
@@ -117,7 +118,7 @@ TEST(big_int_serializes_ok) {
static u8 buf[12];
static u8 expected_in[] = { 0x04, 0xff, 0xff, 0xff, 0x7f,
0x04, 0xff, 0xff, 0xff, 0x7f, OP_ADD };
- static u8 expected_out[] = { 0x05, 0xfe, 0xff, 0xff, 0xff, 0 };
+ static u8 expected_out[] = { 0xfe, 0xff, 0xff, 0xff, 0 };
script_push_int(script, 2147483647LL);
script_push_int(script, 2147483647LL);
@@ -129,7 +130,7 @@ TEST(big_int_serializes_ok) {
"big int input serializes ok");
script_eval(buf, ARRAY_SIZE(expected_in), stack, result);
- script_serialize(stack, buf, ARRAY_SIZE(buf), &len);
+ stack_serialize(stack, buf, ARRAY_SIZE(buf), &len);
cmp_data(buf, expected_out, len, ARRAY_SIZE(expected_out),
"big int output serializes ok");
@@ -141,16 +142,28 @@ TEST(test_small_int) {
static u8 expected_in[] = { 0x01, 0x7f };
script_push_int(script, 127);
- script_serialize(script, buf, ARRAY_SIZE(buf), &len);
- cmp_data(buf, expected_in, len, ARRAY_SIZE(expected_in),
+ script_serialize(script, buf, sizeof(buf), &len);
+ cmp_data(buf, expected_in, len, sizeof(expected_in),
"small integer input serializes ok");
- script_eval(buf, ARRAY_SIZE(expected_in), stack, result);
- script_serialize(stack, buf, ARRAY_SIZE(buf), &len);
- cmp_data(buf, expected_in, len, ARRAY_SIZE(expected_in),
+ script_eval(buf, sizeof(expected_in), stack, result);
+ stack_serialize(stack, buf, sizeof(buf), &len);
+ cmp_data(buf, expected_in, len, sizeof(expected_in),
"small integer output serializes ok");
}
+void test_sn_serialize_small() {
+ static u8 buf[2] = {0};
+ struct num sn;
+ static u8 expected_serial[] = { 0x01, 0x7f };
+ u16 len;
+ sn_from_int(127, &sn);
+ sn_serialize(&sn, buf, sizeof(buf), &len);
+
+ cmp_data(buf, expected_serial, len, sizeof(expected_serial),
+ "small scriptnum (127) serializes ok");
+}
+
// TODO test scriptnum overflows
// TODO test scriptnum negative zero boolean logic
// TODO test scriptnum add into overflow + hash
diff --git a/val.c b/val.c
@@ -31,11 +31,10 @@ val_from_int(s64 intval) {
void val_bytes(struct val val, u32 *len, u8 *buf, int bufsize) {
if (val.type == VT_DATA)
val.type = VT_RAW;
- static const int serialize_minimal = 0;
- val_serialize(val, len, buf, bufsize, serialize_minimal);
+ val_serialize(val, len, buf, bufsize);
}
-void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize, int serialize_minimal) {
+void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) {
struct num *sn;
int n;
u16 valsize;
@@ -44,15 +43,7 @@ void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize, int serialize
sn = num_pool_get(val.ind);
assert(sn);
- if (serialize_minimal) {
- if (sn->val == -1) { *len = 1; *buf = OP_1NEGATE; return; }
- if (sn->val == 0 ) { *len = 1; *buf = 0; return; }
- if (sn->val >= 1 && sn->val <= 16 ) {
- *len = 1;
- *buf = OP_1 - 1 + sn->val;
- return;
- }
- }
+ /// TODO: if serialize_minimal
sn_serialize(sn, buf, bufsize, &valsize);
assert(valsize <= 0xFF);
*len = valsize;
@@ -130,8 +121,8 @@ val_eq(struct val a, struct val b, int require_minimal) {
// TODO: do I need to serialize to compare?
/* abytes = val_serialize(a, &alen, require_minimal); */
/* bbytes = val_serialize(b, &blen, require_minimal); */
- val_serialize(a, &alen, tmpa, tmpsize, 0);
- val_serialize(b, &blen, tmpb, tmpsize, 0);
+ val_serialize(a, &alen, tmpa, tmpsize);
+ val_serialize(b, &blen, tmpb, tmpsize);
// TODO: what if they're semantically equivalent? or does that matter
// (eg. minimal vs not miniminal)?
diff --git a/val.h b/val.h
@@ -38,7 +38,7 @@ u32 val_size(struct val val);
int
val_eq(struct val a, struct val b, int require_minimal);
-void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize, int serialize_minimal);
+void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize);
void val_bytes(struct val val, u32 *len, u8 *buf, int bufsize);
struct val val_from_int(s64);