forked from microsoft/devicescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshow_value.c
More file actions
193 lines (179 loc) · 5.72 KB
/
show_value.c
File metadata and controls
193 lines (179 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include "devs_internal.h"
void devs_log_value(devs_ctx_t *ctx, const char *lbl, value_t v) {
DMESG("%s: %s", lbl, devs_show_value(ctx, v));
char c0 = *lbl;
if (c0 != '!' && c0 != '*' && c0 != '>')
c0 = ' ';
devs_map_t *map = devs_value_to_gc_obj(ctx, v);
if (devs_is_map(map)) {
for (unsigned i = 0; i < map->length; i++) {
if (i > 10) {
DMESG("%c ...", c0);
break;
}
DMESG("%c %s =>", c0, devs_show_value(ctx, map->data[i * 2]));
DMESG("%c %s", c0, devs_show_value(ctx, map->data[i * 2 + 1]));
}
}
}
#if JD_64
static char buf[128];
#else
static char buf[64];
#endif
const char *devs_show_value0(devs_ctx_t *ctx, value_t v) {
if (devs_is_tagged_int(v)) {
jd_sprintf(buf, sizeof(buf), "%d", (int)v.val_int32);
return buf;
}
const char *fmt = NULL;
uint32_t hv;
switch (devs_handle_type(v)) {
case DEVS_HANDLE_TYPE_FLOAT64:
jd_sprintf(buf, sizeof(buf), "%f", devs_value_to_double(ctx, v));
return buf;
case DEVS_HANDLE_TYPE_SPECIAL:
switch ((hv = devs_handle_value(v))) {
case DEVS_SPECIAL_NULL:
return "null";
case DEVS_SPECIAL_UNDEFINED:
return "undefined";
case DEVS_SPECIAL_FALSE:
return "false";
case DEVS_SPECIAL_TRUE:
return "true";
case DEVS_SPECIAL_INF:
return "Infinity";
case DEVS_SPECIAL_MINF:
return "-Infinity";
case DEVS_SPECIAL_NAN:
return "NaN";
default:
if (devs_handle_is_builtin(hv)) {
jd_sprintf(buf, sizeof(buf), "builtin_obj:%d",
(int)hv - DEVS_SPECIAL_BUILTIN_OBJ_FIRST);
return buf;
} else if (devs_handle_is_throw_jmp(hv)) {
unsigned lev;
int pc = devs_handle_decode_throw_jmp_pc(hv, &lev);
jd_sprintf(buf, sizeof(buf), "throw:%d@%u", pc, lev);
return buf;
}
return "?special";
}
case DEVS_HANDLE_TYPE_FIBER:
fmt = "fib";
break;
case DEVS_HANDLE_TYPE_STATIC_FUNCTION:
fmt = "fun";
break;
case DEVS_HANDLE_TYPE_IMG_BUFFERISH:
fmt = devs_bufferish_is_buffer(v) ? "buf" : "str";
break;
case DEVS_HANDLE_TYPE_ROLE:
fmt = "role";
break;
case DEVS_HANDLE_TYPE_ROLE_MEMBER:
fmt = "role_member";
break;
case DEVS_HANDLE_TYPE_BOUND_FUNCTION_STATIC:
jd_sprintf(buf, sizeof(buf), "method:%d:%x", (int)devs_handle_high_value(v),
(unsigned)devs_handle_value(v));
return buf;
case DEVS_HANDLE_TYPE_BOUND_FUNCTION:
jd_sprintf(buf, sizeof(buf), "method:%d:%p", (int)devs_handle_high_value(v),
devs_handle_ptr_value(ctx, v));
return buf;
case DEVS_HANDLE_TYPE_CLOSURE:
jd_sprintf(buf, sizeof(buf), "closure:%d:%p", (int)devs_handle_high_value(v),
devs_handle_ptr_value(ctx, v));
return buf;
case DEVS_HANDLE_TYPE_GC_OBJECT:
switch (devs_gc_tag(devs_handle_ptr_value(ctx, v))) {
case DEVS_GC_TAG_ARRAY:
fmt = "array";
break;
case DEVS_GC_TAG_BUFFER:
fmt = "buffer";
break;
case DEVS_GC_TAG_IMAGE:
fmt = "image";
break;
case DEVS_GC_TAG_STRING_JMP:
case DEVS_GC_TAG_STRING:
fmt = "string";
break;
case DEVS_GC_TAG_PACKET:
fmt = "packet";
break;
case DEVS_GC_TAG_SHORT_MAP:
case DEVS_GC_TAG_HALF_STATIC_MAP:
case DEVS_GC_TAG_MAP:
fmt = "map";
break;
case DEVS_GC_TAG_FREE:
fmt = "?free";
break;
case DEVS_GC_TAG_BYTES:
fmt = "bytes";
break;
case DEVS_GC_TAG_BOUND_FUNCTION:
fmt = "bound";
break;
default:
fmt = "???";
break;
}
jd_sprintf(buf, sizeof(buf), "%s:%p", fmt, devs_handle_ptr_value(ctx, v));
return buf;
}
if (fmt)
jd_sprintf(buf, sizeof(buf), "%s:%u", fmt, (unsigned)devs_handle_value(v));
else
return "?value";
return buf;
}
const char *devs_show_value(devs_ctx_t *ctx, value_t v) {
bool isFun = false;
switch (devs_handle_type(v)) {
case DEVS_HANDLE_TYPE_STATIC_FUNCTION:
case DEVS_HANDLE_TYPE_BOUND_FUNCTION:
case DEVS_HANDLE_TYPE_BOUND_FUNCTION_STATIC:
case DEVS_HANDLE_TYPE_CLOSURE:
isFun = true;
break;
case DEVS_HANDLE_TYPE_GC_OBJECT:
isFun = devs_gc_tag(devs_handle_ptr_value(ctx, v)) == DEVS_GC_TAG_BOUND_FUNCTION;
break;
}
if (!isFun) {
const char *s = devs_string_get_utf8(ctx, v, NULL);
if (s)
return s;
return devs_show_value0(ctx, v);
}
value_t this_val;
devs_activation_t *closure;
int fnidx = devs_get_fnidx(ctx, v, &this_val, &closure);
unsigned off = 0;
if (!devs_is_undefined(this_val)) {
const char *tmp = devs_show_value0(ctx, this_val);
if (tmp != buf)
jd_sprintf(buf, sizeof(buf), "%s", tmp);
off = strlen(buf);
if (off >= sizeof(buf) - 25) {
strcpy(buf, "?.");
off = 2;
} else {
buf[off++] = '.';
}
}
if (closure != NULL) {
uint32_t clo = devs_handle_value(devs_value_from_gc_obj(ctx, closure));
jd_sprintf(buf + off, sizeof(buf) - off, "%x", (unsigned)clo);
off = strlen(buf);
buf[off++] = '@';
}
jd_sprintf(buf + off, sizeof(buf) - off, "fun:%d", fnidx);
return buf;
}