Skip to content

Commit fe8a12e

Browse files
committed
add arbitrary static buffers
1 parent d46c1c5 commit fe8a12e

7 files changed

Lines changed: 86 additions & 17 deletions

File tree

runtime/devicescript/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-> some opcode have some bits inlined
88

99
* extensibility via services and compiler
10-
* allow allocating buffers (global indexed namespace?); extend set/getnum opcode to write to these buffers; allow copying between buffers
10+
* allow copying between buffers
1111

1212
What needs to be passed as arguments?
1313
* global address

runtime/devicescript/buffer.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#include "jacs_internal.h"
22
#include <limits.h>
33

4+
void *jacs_buffer_ptr(jacs_ctx_t *ctx, unsigned idx) {
5+
if (idx == 0)
6+
return ctx->packet.data;
7+
return ctx->buffers + ctx->buffers[idx - 1];
8+
}
9+
410
// shift_val(10) = 1024
511
// shift_val(0) = 1
612
// shift_val(-10) = 1/1024
@@ -31,7 +37,7 @@ static double clamp_double(value_t v, double l, double h) {
3137
#define SET_VAL(SZ, l, h) \
3238
case JACS_NUMFMT_##SZ: \
3339
SZ = clamp_int(q, l, h); \
34-
memcpy(pkt->data + offset, &SZ, sizeof(SZ)); \
40+
memcpy(data, &SZ, sizeof(SZ)); \
3541
break
3642

3743
#define SET_VAL_U(SZ, l, h) \
@@ -40,24 +46,24 @@ static double clamp_double(value_t v, double l, double h) {
4046
SZ = q.val_int32; \
4147
else \
4248
SZ = clamp_double(q, l, h); \
43-
memcpy(pkt->data + offset, &SZ, sizeof(SZ)); \
49+
memcpy(data, &SZ, sizeof(SZ)); \
4450
break
4551

4652
#define SET_VAL_R(SZ) \
4753
case JACS_NUMFMT_##SZ: \
4854
SZ = jacs_value_to_double(q); \
49-
memcpy(pkt->data + offset, &SZ, sizeof(SZ)); \
55+
memcpy(data, &SZ, sizeof(SZ)); \
5056
break
5157

5258
#define GET_VAL_INT(SZ) \
5359
case JACS_NUMFMT_##SZ: \
54-
memcpy(&SZ, pkt->data + offset, sizeof(SZ)); \
60+
memcpy(&SZ, data, sizeof(SZ)); \
5561
I32 = SZ; \
5662
break;
5763

5864
#define GET_VAL_UINT(SZ) \
5965
case JACS_NUMFMT_##SZ: \
60-
memcpy(&SZ, pkt->data + offset, sizeof(SZ)); \
66+
memcpy(&SZ, data, sizeof(SZ)); \
6167
if (SZ <= INT_MAX) \
6268
I32 = SZ; \
6369
else { \
@@ -68,12 +74,12 @@ static double clamp_double(value_t v, double l, double h) {
6874

6975
#define GET_VAL_DBL(SZ) \
7076
case JACS_NUMFMT_##SZ: \
71-
memcpy(&SZ, pkt->data + offset, sizeof(SZ)); \
77+
memcpy(&SZ, data, sizeof(SZ)); \
7278
is_float = 1; \
7379
F64 = SZ; \
7480
break;
7581

76-
value_t jacs_buffer_op(jacs_activation_t *frame, uint16_t offset, uint16_t fmt0, uint16_t buffer,
82+
value_t jacs_buffer_op(jacs_activation_t *frame, uint16_t fmt0, uint16_t offset, uint16_t buffer,
7783
value_t *setv) {
7884
int is_float = 0;
7985

@@ -92,20 +98,28 @@ value_t jacs_buffer_op(jacs_activation_t *frame, uint16_t offset, uint16_t fmt0,
9298
unsigned shift = fmt0 >> 4;
9399
unsigned sz = 1 << (fmt & 0b11);
94100

101+
//if (!setv)
102+
// DMESG("GET @%d fmt=%x buf=%d", offset, fmt0, buffer);
103+
95104
jacs_ctx_t *ctx = frame->fiber->ctx;
96105
jd_packet_t *pkt = &ctx->packet;
97106

98-
if ((fmt == 0b1000 || fmt == 0b1001) || shift > sz * 8)
99-
jacs_runtime_failure(ctx);
107+
if ((fmt == 0b1000 || fmt == 0b1001) || shift > sz * 8 ||
108+
buffer >= jacs_img_num_buffers(&ctx->img))
109+
return jacs_runtime_failure(ctx);
100110

101-
if (offset + sz > pkt->service_size) {
111+
unsigned bufsz = buffer == 0 ? pkt->service_size : jacs_img_get_buffer(&ctx->img, buffer)->size;
112+
113+
if (offset + sz > bufsz) {
102114
// DMESG("gv NAN at pc=%d sz=%d %x", frame->pc, pkt->service_size, pkt->service_command);
103115
if (setv)
104116
return jacs_runtime_failure(ctx);
105117
else
106118
return jacs_nan;
107119
}
108120

121+
uint8_t *data = jacs_buffer_ptr(ctx, buffer) + offset;
122+
109123
if (setv) {
110124
value_t q = *setv;
111125
if (shift || !jacs_is_tagged_int(q)) {

runtime/devicescript/jacs_format.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,24 @@ typedef struct {
66
uint32_t length; // in bytes
77
} jacs_img_section_t;
88

9-
#define JACS_NUM_IMG_SECTIONS 6
9+
#define JACS_NUM_IMG_SECTIONS 7
10+
11+
#define JACS_IMG_VERSION 0x00010001
1012

1113
typedef struct {
1214
uint32_t magic0;
1315
uint32_t magic1;
16+
uint32_t version;
1417
uint16_t num_globals;
15-
uint8_t reserved[64 - 4 - 4 - 2];
18+
uint8_t reserved[64 - 4 - 4 - 4 - 2];
1619

1720
jacs_img_section_t functions; // jacs_function_desc_t[]
1821
jacs_img_section_t functions_data; // uint16_t[]
1922
jacs_img_section_t float_literals; // value_t[]
2023
jacs_img_section_t roles; // jacs_role_desc_t[]
2124
jacs_img_section_t strings; // jacs_img_section_t[]
2225
jacs_img_section_t string_data; // "strings" points in here
26+
jacs_img_section_t buffers; // jacs_buffer_desc_t[]
2327
} jacs_img_header_t;
2428

2529
typedef struct {
@@ -38,6 +42,12 @@ typedef struct {
3842
uint16_t reserved;
3943
} jacs_role_desc_t;
4044

45+
typedef struct {
46+
uint32_t type; // currently always 0
47+
uint16_t size;
48+
uint16_t reserved;
49+
} jacs_buffer_desc_t;
50+
4151
#define JACS_IMG_MAGIC0 0x5363614a // "JacS"
4252
#define JACS_IMG_MAGIC1 0x9a6a7e0a
4353

runtime/devicescript/jacs_img.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ static inline uint32_t jacs_img_num_floats(const jacs_img_t *img) {
2929
return img->header->float_literals.length / sizeof(value_t);
3030
}
3131

32+
static inline uint32_t jacs_img_num_buffers(const jacs_img_t *img) {
33+
return img->header->buffers.length / sizeof(jacs_buffer_desc_t);
34+
}
35+
3236
static inline const jacs_function_desc_t *jacs_img_get_function(const jacs_img_t *img,
3337
uint32_t idx) {
3438
return (const jacs_function_desc_t *)(img->data + img->header->functions.start +
@@ -47,6 +51,11 @@ static inline value_t jacs_img_get_float(const jacs_img_t *img, uint32_t idx) {
4751
return v;
4852
}
4953

54+
static inline const jacs_buffer_desc_t *jacs_img_get_buffer(const jacs_img_t *img, uint32_t idx) {
55+
return (const jacs_buffer_desc_t *)(img->data + img->header->buffers.start +
56+
idx * sizeof(jacs_buffer_desc_t));
57+
}
58+
5059
static inline bool jacs_is_prefix_instr(uint16_t instr) {
5160
return (instr >> 12) <= JACS_OPTOP_SET_HIGH;
5261
}

runtime/devicescript/jacs_internal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ struct jacs_ctx {
8383
jacs_fiber_t *fibers;
8484
jd_role_t **roles;
8585

86+
uint32_t *buffers;
87+
8688
uint32_t _prev_us;
8789
uint32_t _now;
8890

@@ -157,4 +159,6 @@ value_t jacs_step_binop(int op, value_t a, value_t b);
157159
value_t jacs_step_opmath1(int op, value_t a);
158160
value_t jacs_step_opmath2(int op, value_t a, value_t b);
159161

160-
value_t jacs_buffer_op(jacs_activation_t *frame, uint16_t fmt0, uint16_t offset, uint16_t buffer, value_t *setv);
162+
value_t jacs_buffer_op(jacs_activation_t *frame, uint16_t fmt0, uint16_t offset, uint16_t buffer,
163+
value_t *setv);
164+
void *jacs_buffer_ptr(jacs_ctx_t *ctx, unsigned idx);

runtime/devicescript/jacscript.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@ static void setup_ctx(jacs_ctx_t *ctx, const uint8_t *img) {
66
ctx->globals = jd_alloc(sizeof(value_t) * ctx->img.header->num_globals);
77
ctx->roles = jd_alloc(sizeof(jd_role_t *) * jacs_img_num_roles(&ctx->img));
88

9+
uint32_t num_buffers = jacs_img_num_buffers(&ctx->img);
10+
if (num_buffers > 1) {
11+
uint32_t buffer_words = num_buffers - 1;
12+
for (unsigned i = 1; i < num_buffers; ++i) {
13+
buffer_words += (jacs_img_get_buffer(&ctx->img, i)->size + 3) >> 2;
14+
}
15+
ctx->buffers = jd_alloc(sizeof(uint32_t) * buffer_words);
16+
buffer_words = num_buffers - 1;
17+
uint32_t *bufptr = ctx->buffers;
18+
for (unsigned i = 1; i < num_buffers; ++i) {
19+
*bufptr++ = buffer_words;
20+
buffer_words += (jacs_img_get_buffer(&ctx->img, i)->size + 3) >> 2;
21+
}
22+
}
23+
924
jacs_fiber_sync_now(ctx);
1025
jacs_jd_reset_packet(ctx);
1126

@@ -71,6 +86,7 @@ static void clear_ctx(jacs_ctx_t *ctx) {
7186
jacs_fiber_free_all_fibers(ctx);
7287
jd_free(ctx->globals);
7388
jd_free(ctx->roles);
89+
jd_free(ctx->buffers);
7490
memset(ctx, 0, sizeof(*ctx));
7591
}
7692

runtime/devicescript/verify.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "jacs_internal.h"
22
#include <math.h>
33

4-
STATIC_ASSERT(sizeof(jacs_img_header_t) == 64 + 6 * sizeof(jacs_img_section_t));
4+
STATIC_ASSERT(sizeof(jacs_img_header_t) == 64 + JACS_NUM_IMG_SECTIONS * sizeof(jacs_img_section_t));
55

66
static int numSetBits(uint32_t n) {
77
int r = 0;
@@ -20,7 +20,7 @@ static int fail(int code, uint32_t offset) {
2020
return -code;
2121
}
2222

23-
// next error 1149 / 1045
23+
// next error 1149 / 1051
2424
#define CHECK(code, cond) \
2525
if (!(cond)) \
2626
return fail(code, offset)
@@ -164,6 +164,7 @@ static int verify_function(jacs_img_t *img, const jacs_function_desc_t *fptr) {
164164
} else {
165165
CHECK(1137, IS_DYNAMIC(c) || c <= 236U - 1); // offset in range
166166
}
167+
CHECK(1149, IS_DYNAMIC(d) || d <= jacs_img_num_buffers(img));
167168
} break;
168169
case JACS_CELL_KIND_FLOAT_CONST:
169170
CHECK(1138, idx < jacs_img_num_floats(img)); // float const in range
@@ -277,7 +278,7 @@ static int verify_function(jacs_img_t *img, const jacs_function_desc_t *fptr) {
277278
break;
278279
case JACS_OPASYNC_QUERY_REG: // A-role, B-code, C-timeout
279280
CHECK(1126, IS_DYNAMIC(a) || a < jacs_img_num_roles(img)); // role idx
280-
CHECK(1127, IS_DYNAMIC(b) || b <= 0x1ff); // reg code
281+
CHECK(1127, IS_DYNAMIC(b) || b <= 0x1ff); // reg code
281282
break;
282283
case JACS_OPASYNC_QUERY_IDX_REG: // A-role, B-STRIDX:CMD[8], C-timeout
283284
CHECK(1128, IS_DYNAMIC(a) || a < jacs_img_num_roles(img)); // role idx
@@ -316,6 +317,7 @@ int jacs_verify(const uint8_t *imgdata, uint32_t size) {
316317
jacs_img_t *img = &_img;
317318

318319
CHECK(1000, header->magic0 == JACS_IMG_MAGIC0 && header->magic1 == JACS_IMG_MAGIC1);
320+
CHECK(1050, header->version == JACS_IMG_VERSION);
319321

320322
const jacs_img_section_t *sptr = &header->functions;
321323

@@ -367,5 +369,19 @@ int jacs_verify(const uint8_t *imgdata, uint32_t size) {
367369
CHECK(1042, fptr->name_idx < jacs_img_num_strings(img));
368370
}
369371

372+
for (const jacs_buffer_desc_t *fptr = FIRST_DESC(buffers); //
373+
(void *)fptr < LAST_DESC(buffers); //
374+
fptr++) {
375+
SET_OFF(fptr);
376+
CHECK(1045, fptr->type == 0);
377+
CHECK(1046, fptr->reserved == 0);
378+
if (fptr == FIRST_DESC(buffers)) {
379+
CHECK(1049, fptr->size == JD_SERIAL_PAYLOAD_SIZE); // buffer #0 is current packet
380+
} else {
381+
CHECK(1047, fptr->size > 0);
382+
CHECK(1048, fptr->size <= 1024);
383+
}
384+
}
385+
370386
return 0;
371387
}

0 commit comments

Comments
 (0)