summaryrefslogtreecommitdiffhomepage
path: root/vm.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-04-21 15:07:16 +0200
committerJo-Philipp Wich <jo@mein.io>2021-04-25 20:48:40 +0200
commit35af4ba4fc21a4b2357c50e6b02a2e3e4b236e88 (patch)
tree445f9fdf2e96e490cd681dca36d5cc9912474ed3 /vm.c
parentf2c4b79feaffd7b2fdb4041f47c9cd0f4cc3bc6e (diff)
treewide: rework internal data type system
Instead of relying on json_object values internally, use custom types to represent the different ucode value types which brings a number of advantages compared to the previous approach: - Due to the use of tagged pointers, small integer, string and bool values can be stored directly in the pointer addresses, vastly reducing required heap memory - Ability to create circular data structures such as `let o; o = { test: o };` - Ability to register custom `tostring()` function through prototypes - Initial mark/sweep GC implementation to tear down circular object graphs on VM deinit The change also paves the way for possible future extensions such as constant variables and meta methods for custom ressource types. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c1039
1 files changed, 549 insertions, 490 deletions
diff --git a/vm.c b/vm.c
index ce1aa0c..10e3286 100644
--- a/vm.c
+++ b/vm.c
@@ -51,8 +51,8 @@ static const uc_insn_definition insn_defs[__I_MAX] = {
[I_LUPV] = { 0, 1, 4 },
[I_LVAL] = { 2, 1, 0 },
- [I_CLFN] = { 0, 1, 4, true },
- [I_ARFN] = { 0, 1, 4, true },
+ [I_CLFN] = { 0, 1, 4 },
+ [I_ARFN] = { 0, 1, 4 },
[I_SLOC] = { 0, 0, 4 },
[I_SUPV] = { 0, 0, 4 },
@@ -90,8 +90,8 @@ static const uc_insn_definition insn_defs[__I_MAX] = {
[I_GT] = { 2, 1, 0 },
[I_IN] = { 2, 1, 0 },
- [I_JMP] = { 0, 0, -4, true },
- [I_JMPZ] = { 1, 0, -4, true },
+ [I_JMP] = { 0, 0, -4 },
+ [I_JMPZ] = { 1, 0, -4 },
[I_COPY] = { 0, 1, 1 },
[I_POP] = { 1, 0, 0 },
@@ -124,19 +124,19 @@ uc_vm_reset_stack(uc_vm *vm)
{
while (vm->stack.count > 0) {
vm->stack.count--;
- uc_value_put(vm->stack.entries[vm->stack.count]);
+ ucv_put(vm->stack.entries[vm->stack.count]);
vm->stack.entries[vm->stack.count] = NULL;
}
}
-static json_object *
+static uc_value_t *
uc_vm_callframe_pop(uc_vm *vm);
static void
uc_vm_reset_callframes(uc_vm *vm)
{
while (vm->callframes.count > 0)
- uc_value_put(uc_vm_callframe_pop(vm));
+ ucv_put(uc_vm_callframe_pop(vm));
}
void uc_vm_init(uc_vm *vm, uc_parse_config *config)
@@ -152,19 +152,22 @@ void uc_vm_init(uc_vm *vm, uc_parse_config *config)
vm->open_upvals = NULL;
+ vm->values.prev = &vm->values;
+ vm->values.next = &vm->values;
+
uc_vm_reset_stack(vm);
}
void uc_vm_free(uc_vm *vm)
{
- uc_upvalref *ref;
+ uc_upvalref_t *ref;
- uc_value_put(vm->exception.stacktrace);
+ ucv_put(vm->exception.stacktrace);
free(vm->exception.message);
while (vm->open_upvals) {
ref = vm->open_upvals->next;
- uc_value_put(vm->open_upvals->header.jso);
+ ucv_put(&vm->open_upvals->header);
vm->open_upvals = ref;
}
@@ -172,6 +175,8 @@ void uc_vm_free(uc_vm *vm)
uc_vm_reset_stack(vm);
uc_vector_clear(&vm->stack);
uc_vector_clear(&vm->callframes);
+
+ ucv_gc(vm, true);
}
static uc_chunk *
@@ -263,11 +268,12 @@ static void
uc_vm_frame_dump(uc_vm *vm, uc_callframe *frame)
{
uc_chunk *chunk = uc_vm_frame_chunk(frame);
- uc_function *function;
- uc_closure *closure;
- uc_upvalref *ref;
- json_object *v;
+ uc_function_t *function;
+ uc_closure_t *closure;
+ uc_upvalref_t *ref;
+ uc_value_t *v;
size_t i;
+ char *s;
fprintf(stderr, " [*] CALLFRAME[%zx]\n",
frame - vm->callframes.entries);
@@ -275,8 +281,9 @@ uc_vm_frame_dump(uc_vm *vm, uc_callframe *frame)
fprintf(stderr, " |- stackframe %zu/%zu\n",
frame->stackframe, vm->stack.count);
- fprintf(stderr, " |- ctx %s\n",
- json_object_to_json_string(frame->ctx));
+ s = ucv_to_string(NULL, frame->ctx);
+ fprintf(stderr, " |- ctx %s\n", s);
+ free(s);
if (chunk) {
fprintf(stderr, " |- %zu constants\n",
@@ -284,12 +291,10 @@ uc_vm_frame_dump(uc_vm *vm, uc_callframe *frame)
for (i = 0; i < chunk->constants.isize; i++) {
v = uc_chunk_get_constant(chunk, i);
-
- fprintf(stderr, " | [%zu] %s\n",
- i,
- json_object_to_json_string(v));
-
- uc_value_put(v);
+ s = ucv_to_jsonstring(NULL, v);
+ fprintf(stderr, " | [%zu] %s\n", i, s);
+ free(s);
+ ucv_put(v);
}
closure = frame->closure;
@@ -301,80 +306,88 @@ uc_vm_frame_dump(uc_vm *vm, uc_callframe *frame)
for (i = 0; i < function->nupvals; i++) {
ref = closure->upvals[i];
v = uc_chunk_debug_get_variable(chunk, 0, i, true);
+ s = ucv_to_string(NULL, v);
+ fprintf(stderr, " [%zu] <%p> %s ", i, ref, s);
+ free(s);
- if (ref->closed)
- fprintf(stderr, " [%zu] <%p> %s {closed} %s\n",
- i,
- ref,
- json_object_to_json_string(v),
- json_object_to_json_string(ref->value));
- else
- fprintf(stderr, " [%zu] <%p> %s {open[%zu]} %s\n",
- i,
- ref,
- json_object_to_json_string(v),
- ref->slot,
- json_object_to_json_string(vm->stack.entries[ref->slot]));
-
- uc_value_put(v);
+ if (ref->closed) {
+ s = ucv_to_jsonstring(NULL, ref->value);
+ fprintf(stderr, "{closed} %s\n", s);
+ }
+ else {
+ s = ucv_to_jsonstring(NULL, vm->stack.entries[ref->slot]);
+ fprintf(stderr, "{open[%zu]} %s\n", ref->slot, s);
+ }
+
+ ucv_put(v);
+ free(s);
}
}
}
void
-uc_vm_stack_push(uc_vm *vm, json_object *value)
+uc_vm_stack_push(uc_vm *vm, uc_value_t *value)
{
+ char *s;
+
uc_vector_grow(&vm->stack);
- uc_value_put(vm->stack.entries[vm->stack.count]);
+ ucv_put(vm->stack.entries[vm->stack.count]);
vm->stack.entries[vm->stack.count] = value;
vm->stack.count++;
- if (vm->trace)
- fprintf(stderr, " [+%zd] %s\n",
- vm->stack.count - 1,
- json_object_to_json_string(value));
+ if (vm->trace) {
+ s = ucv_to_jsonstring(NULL, value);
+ fprintf(stderr, " [+%zd] %s\n", vm->stack.count - 1, s);
+ free(s);
+ }
}
-json_object *
+uc_value_t *
uc_vm_stack_pop(uc_vm *vm)
{
- json_object *rv;
+ uc_value_t *rv;
+ char *s;
vm->stack.count--;
rv = vm->stack.entries[vm->stack.count];
vm->stack.entries[vm->stack.count] = NULL;
- if (vm->trace)
- fprintf(stderr, " [-%zd] %s\n",
- vm->stack.count,
- json_object_to_json_string(rv));
+ if (vm->trace) {
+ s = ucv_to_jsonstring(NULL, rv);
+ fprintf(stderr, " [-%zd] %s\n", vm->stack.count, s);
+ free(s);
+ }
return rv;
}
-json_object *
+uc_value_t *
uc_vm_stack_peek(uc_vm *vm, size_t offset)
{
return vm->stack.entries[vm->stack.count + (-1 - offset)];
}
static void
-uc_vm_stack_set(uc_vm *vm, size_t offset, json_object *value)
+uc_vm_stack_set(uc_vm *vm, size_t offset, uc_value_t *value)
{
- if (vm->trace)
- fprintf(stderr, " [!%zu] %s\n",
- offset, json_object_to_json_string(value));
+ char *s;
- uc_value_put(vm->stack.entries[offset]);
+ if (vm->trace) {
+ s = ucv_to_jsonstring(NULL, value);
+ fprintf(stderr, " [!%zu] %s\n", offset, s);
+ free(s);
+ }
+
+ ucv_put(vm->stack.entries[offset]);
vm->stack.entries[offset] = value;
}
static void
-uc_vm_call_native(uc_vm *vm, json_object *ctx, uc_cfunction *fptr, bool mcall, size_t nargs)
+uc_vm_call_native(uc_vm *vm, uc_value_t *ctx, uc_cfunction_t *fptr, bool mcall, size_t nargs)
{
- json_object *res = NULL;
+ uc_value_t *res = NULL;
uc_callframe *frame;
/* add new callframe */
@@ -393,24 +406,25 @@ uc_vm_call_native(uc_vm *vm, json_object *ctx, uc_cfunction *fptr, bool mcall, s
res = fptr->cfn(vm, nargs);
/* reset stack */
- uc_value_put(uc_vm_callframe_pop(vm));
+ ucv_put(uc_vm_callframe_pop(vm));
/* push return value */
if (!vm->exception.type)
uc_vm_stack_push(vm, res);
else
- uc_value_put(res);
+ ucv_put(res);
}
static bool
-uc_vm_call_function(uc_vm *vm, json_object *ctx, json_object *fno, bool mcall, size_t argspec)
+uc_vm_call_function(uc_vm *vm, uc_value_t *ctx, uc_value_t *fno, bool mcall, size_t argspec)
{
size_t i, j, stackoff, nargs = argspec & 0xffff, nspreads = argspec >> 16;
uc_callframe *frame = uc_vm_current_frame(vm);
- json_object *ellip, *arg;
- uc_function *function;
- uc_closure *closure;
+ uc_value_t *ellip, *arg;
+ uc_function_t *function;
+ uc_closure_t *closure;
uint16_t slot, tmp;
+ char *s;
/* XXX: make dependent on stack size */
if (vm->callframes.count >= 1000) {
@@ -424,11 +438,11 @@ uc_vm_call_function(uc_vm *vm, json_object *ctx, json_object *fno, bool mcall, s
/* argument list contains spread operations, we need to reshuffle the stack */
if (nspreads > 0) {
/* create temporary array */
- ellip = xjs_new_array_size(nargs);
+ ellip = ucv_array_new_length(vm, nargs);
/* pop original stack values and push to temp array in reverse order */
for (i = 0; i < nargs; i++)
- json_object_array_add(ellip, uc_vm_stack_pop(vm));
+ ucv_array_push(ellip, uc_vm_stack_pop(vm));
/* for each spread value index ... */
for (i = 0, slot = nargs; i < nspreads; i++) {
@@ -437,61 +451,61 @@ uc_vm_call_function(uc_vm *vm, json_object *ctx, json_object *fno, bool mcall, s
frame->ip += 2;
/* push each preceeding non-spread value to the stack */
- for (j = slot; j > tmp + 1; j--)
- uc_vm_stack_push(vm, uc_value_get(json_object_array_get_idx(ellip, j - 1)));
+ for (j = slot; j > tmp + 1UL; j--)
+ uc_vm_stack_push(vm, ucv_get(ucv_array_get(ellip, j - 1)));
/* read spread value at index... */
slot = tmp;
- arg = uc_value_get(json_object_array_get_idx(ellip, slot));
+ arg = ucv_get(ucv_array_get(ellip, slot));
/* ... ensure that it is an array type ... */
- if (!json_object_is_type(arg, json_type_array)) {
- uc_vm_raise_exception(vm, EXCEPTION_TYPE,
- "(%s) is not iterable",
- json_object_to_json_string(arg));
+ if (ucv_type(arg) != UC_ARRAY) {
+ s = ucv_to_string(vm, arg);
+ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "(%s) is not iterable", s);
+ free(s);
return false;
}
/* ... and push each spread array value as argument to the stack */
- for (j = 0; j < json_object_array_length(arg); j++)
- uc_vm_stack_push(vm, uc_value_get(json_object_array_get_idx(arg, j)));
+ for (j = 0; j < ucv_array_length(arg); j++)
+ uc_vm_stack_push(vm, ucv_get(ucv_array_get(arg, j)));
- uc_value_put(arg);
+ ucv_put(arg);
}
/* push remaining non-spread arguments to the stack */
for (i = slot; i > 0; i--)
- uc_vm_stack_push(vm, uc_value_get(json_object_array_get_idx(ellip, i - 1)));
+ uc_vm_stack_push(vm, ucv_get(ucv_array_get(ellip, i - 1)));
/* free temp array */
- uc_value_put(ellip);
+ ucv_put(ellip);
/* update arg count */
nargs = vm->stack.count - stackoff - 1;
}
/* is a native function */
- if (uc_object_is_type(fno, UC_OBJ_CFUNCTION)) {
- uc_vm_call_native(vm, ctx, uc_object_as_cfunction(fno), mcall, nargs);
+ if (ucv_type(fno) == UC_CFUNCTION) {
+ uc_vm_call_native(vm, ctx, (uc_cfunction_t *)fno, mcall, nargs);
return true;
}
- if (!uc_object_is_type(fno, UC_OBJ_CLOSURE)) {
+ if (ucv_type(fno) != UC_CLOSURE) {
uc_vm_raise_exception(vm, EXCEPTION_TYPE, "left-hand side is not a function");
return false;
}
- closure = uc_object_as_closure(fno);
+ closure = (uc_closure_t *)fno;
function = closure->function;
/* fewer arguments on stack than function expects => pad */
if (nargs < function->nargs) {
for (i = nargs; i < function->nargs; i++) {
if (function->vararg && (i + 1) == function->nargs)
- uc_vm_stack_push(vm, xjs_new_array_size(0));
+ uc_vm_stack_push(vm, ucv_array_new_length(vm, 0));
else
uc_vm_stack_push(vm, NULL);
}
@@ -501,10 +515,10 @@ uc_vm_call_function(uc_vm *vm, json_object *ctx, json_object *fno, bool mcall, s
else if (nargs > function->nargs - function->vararg) {
/* is a vararg function => pass excess args as array */
if (function->vararg) {
- ellip = xjs_new_array_size(nargs - (function->nargs - 1));
+ ellip = ucv_array_new_length(vm, nargs - (function->nargs - 1));
for (i = function->nargs; i <= nargs; i++)
- json_object_array_add(ellip, uc_vm_stack_peek(vm, nargs - i));
+ ucv_array_push(ellip, uc_vm_stack_peek(vm, nargs - i));
for (i = function->nargs; i <= nargs; i++)
uc_vm_stack_pop(vm);
@@ -515,7 +529,7 @@ uc_vm_call_function(uc_vm *vm, json_object *ctx, json_object *fno, bool mcall, s
/* static amount of args => drop excess values */
else {
for (i = function->nargs; i < nargs; i++)
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
}
}
@@ -543,19 +557,19 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
uc_chunk *chunk = uc_vm_frame_chunk(frame);
- size_t msglen = 0, srcpos;
- json_object *cnst = NULL;
- char *msg = NULL;
+ uc_stringbuf_t *buf = NULL;
+ uc_value_t *cnst = NULL;
+ size_t srcpos;
+ char *s;
- srcpos = uc_function_get_srcpos(frame->closure->function, pos - chunk->entries);
+ srcpos = ucv_function_srcpos((uc_value_t *)frame->closure->function, pos - chunk->entries);
if (last_srcpos == 0 || last_source != frame->closure->function->source || srcpos != last_srcpos) {
- format_source_context(&msg, &msglen,
- frame->closure->function->source,
- srcpos, true);
+ buf = xprintbuf_new();
- fprintf(stderr, "%s", msg);
- free(msg);
+ format_source_context(buf, frame->closure->function->source, srcpos, true);
+ fwrite(buf->buf, 1, printbuf_length(buf), stderr);
+ printbuf_free(buf);
last_source = frame->closure->function->source;
last_srcpos = srcpos;
@@ -574,13 +588,13 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
case -2:
fprintf(stderr, " {%c0x%hx}",
vm->arg.s16 < 0 ? '-' : '+',
- vm->arg.s16 < 0 ? -(unsigned)vm->arg.s16 : vm->arg.s16);
+ vm->arg.s16 < 0 ? -(unsigned)vm->arg.s16 : (unsigned)vm->arg.s16);
break;
case -4:
fprintf(stderr, " {%c0x%x}",
vm->arg.s32 < 0 ? '-' : '+',
- vm->arg.s32 < 0 ? -(unsigned)vm->arg.s32 : vm->arg.s32);
+ vm->arg.s32 < 0 ? -(unsigned)vm->arg.s32 : (unsigned)vm->arg.s32);
break;
case 1:
@@ -605,9 +619,11 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
case I_LVAR:
case I_SVAR:
cnst = uc_chunk_get_constant(uc_vm_frame_chunk(uc_vector_last(&vm->callframes)), vm->arg.u32);
+ s = cnst ? ucv_to_jsonstring(NULL, cnst) : NULL;
- fprintf(stderr, "\t; %s", cnst ? json_object_to_json_string(cnst) : "null");
- uc_value_put(cnst);
+ fprintf(stderr, "\t; %s", s ? s : "(?)");
+ ucv_put(cnst);
+ free(s);
break;
case I_LLOC:
@@ -615,9 +631,11 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
case I_SLOC:
case I_SUPV:
cnst = uc_chunk_debug_get_variable(chunk, pos - chunk->entries, vm->arg.u32, (insn == I_LUPV || insn == I_SUPV));
+ s = cnst ? ucv_to_jsonstring(NULL, cnst) : NULL;
- fprintf(stderr, "\t; %s", cnst ? json_object_to_json_string(cnst) : "(?)");
- uc_value_put(cnst);
+ fprintf(stderr, "\t; %s", s ? s : "(?)");
+ ucv_put(cnst);
+ free(s);
break;
case I_ULOC:
@@ -629,11 +647,14 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
if (!cnst)
cnst = uc_chunk_get_constant(uc_vm_frame_chunk(uc_vector_last(&vm->callframes)), vm->arg.u32 & 0x00ffffff);
+ s = cnst ? ucv_to_jsonstring(NULL, cnst) : NULL;
+
fprintf(stderr, "\t; %s (%s)",
- cnst ? json_object_to_json_string(cnst) : "(?)",
+ s ? s : "(?)",
insn_names[vm->arg.u32 >> 24]);
- uc_value_put(cnst);
+ ucv_put(cnst);
+ free(s);
break;
case I_UVAL:
@@ -647,14 +668,38 @@ uc_dump_insn(uc_vm *vm, uint8_t *pos, enum insn_type insn)
fprintf(stderr, "\n");
}
-static int
-uc_vm_exception_tostring(json_object *jso, struct printbuf *pb, int level, int flags)
+static uc_value_t *
+uc_vm_exception_tostring(uc_vm *vm, size_t nargs)
{
- bool strict = (level > 0) || (flags & JSON_C_TO_STRING_STRICT);
- json_object *message = json_object_object_get(jso, "message");
+ uc_callframe *frame = uc_vm_current_frame(vm);
+ uc_value_t *message = ucv_object_get(frame->ctx, "message", NULL);
- return sprintbuf(pb, "%s",
- strict ? json_object_to_json_string(message) : json_object_get_string(message));
+ return message ? ucv_get(message) : ucv_string_new("Exception");
+}
+
+static uc_value_t *exception_prototype = NULL;
+
+static uc_value_t *
+uc_vm_exception_new(uc_vm *vm, uc_exception_type_t type, const char *message, uc_value_t *stacktrace)
+{
+ uc_value_t *exo;
+
+ if (exception_prototype == NULL) {
+ exception_prototype = ucv_object_new(vm);
+
+ ucv_object_add(exception_prototype, "tostring",
+ ucv_cfunction_new("tostring", uc_vm_exception_tostring));
+ }
+
+ exo = ucv_object_new(vm);
+
+ ucv_object_add(exo, "type", ucv_string_new(exception_type_strings[type]));
+ ucv_object_add(exo, "message", ucv_string_new(message));
+ ucv_object_add(exo, "stacktrace", ucv_get(stacktrace));
+
+ ucv_prototype_set(exo, ucv_get(exception_prototype));
+
+ return exo;
}
static bool
@@ -662,7 +707,7 @@ uc_vm_handle_exception(uc_vm *vm)
{
uc_callframe *frame = uc_vm_current_frame(vm);
uc_chunk *chunk = NULL;
- json_object *exo;
+ uc_value_t *exo;
size_t i, pos;
if (!frame->closure)
@@ -680,16 +725,11 @@ uc_vm_handle_exception(uc_vm *vm)
/* we found a matching range... first unwind stack */
while (vm->stack.count > frame->stackframe + chunk->ehranges.entries[i].slot)
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
/* prepare exception object and expose it to user handler code */
- exo = xjs_new_object();
+ exo = uc_vm_exception_new(vm, vm->exception.type, vm->exception.message, vm->exception.stacktrace);
- json_object_object_add(exo, "type", xjs_new_string(exception_type_strings[vm->exception.type]));
- json_object_object_add(exo, "message", xjs_new_string(vm->exception.message));
- json_object_object_add(exo, "stacktrace", uc_value_get(vm->exception.stacktrace));
-
- json_object_set_serializer(exo, uc_vm_exception_tostring, NULL, NULL);
uc_vm_stack_push(vm, exo);
/* reset exception information */
@@ -721,35 +761,35 @@ uc_vm_handle_exception(uc_vm *vm)
return false;
}
-static json_object *
+static uc_value_t *
uc_vm_capture_stacktrace(uc_vm *vm, size_t i)
{
- json_object *stacktrace, *entry, *last = NULL;
- uc_function *function;
+ uc_value_t *stacktrace, *entry, *last = NULL;
+ uc_function_t *function;
uc_callframe *frame;
size_t off, srcpos;
char *name;
- stacktrace = xjs_new_array();
+ stacktrace = ucv_array_new(vm);
for (; i > 0; i--) {
frame = &vm->callframes.entries[i - 1];
- entry = xjs_new_object();
+ entry = ucv_object_new(vm);
if (frame->closure) {
function = frame->closure->function;
off = (frame->ip - uc_vm_frame_chunk(frame)->entries) - 1;
- srcpos = uc_function_get_srcpos(function, off);
+ srcpos = ucv_function_srcpos((uc_value_t *)function, off);
- json_object_object_add(entry, "filename", xjs_new_string(function->source->filename));
- json_object_object_add(entry, "line", xjs_new_int64(uc_source_get_line(function->source, &srcpos)));
- json_object_object_add(entry, "byte", xjs_new_int64(srcpos));
+ ucv_object_add(entry, "filename", ucv_string_new(function->source->filename));
+ ucv_object_add(entry, "line", ucv_int64_new(uc_source_get_line(function->source, &srcpos)));
+ ucv_object_add(entry, "byte", ucv_int64_new(srcpos));
}
if (i > 1) {
if (frame->closure) {
- if (frame->closure->function->name)
+ if (frame->closure->function->name[0])
name = frame->closure->function->name;
else if (frame->closure->is_arrow)
name = "[arrow function]";
@@ -760,29 +800,29 @@ uc_vm_capture_stacktrace(uc_vm *vm, size_t i)
name = frame->cfunction->name;
}
- json_object_object_add(entry, "function", xjs_new_string(name));
+ ucv_object_add(entry, "function", ucv_string_new(name));
}
- if (!json_object_equal(last, entry)) {
- json_object_array_add(stacktrace, entry);
+ if (!ucv_equal(last, entry)) {
+ ucv_array_push(stacktrace, entry);
last = entry;
}
else {
- uc_value_put(entry);
+ ucv_put(entry);
}
}
return stacktrace;
}
-static json_object *
+static uc_value_t *
uc_vm_get_error_context(uc_vm *vm)
{
- json_object *stacktrace;
+ uc_value_t *stacktrace;
uc_callframe *frame;
+ uc_stringbuf_t *buf;
uc_chunk *chunk;
- size_t offset, len = 0, i;
- char *msg = NULL;
+ size_t offset, i;
/* skip to first non-native function call frame */
for (i = vm->callframes.count; i > 0; i--)
@@ -795,17 +835,17 @@ uc_vm_get_error_context(uc_vm *vm)
return NULL;
chunk = uc_vm_frame_chunk(frame);
- offset = uc_function_get_srcpos(frame->closure->function, (frame->ip - chunk->entries) - 1);
+ offset = ucv_function_srcpos((uc_value_t *)frame->closure->function, (frame->ip - chunk->entries) - 1);
stacktrace = uc_vm_capture_stacktrace(vm, i);
+ buf = ucv_stringbuf_new();
+
if (offset)
- format_error_context(&msg, &len, frame->closure->function->source, stacktrace, offset);
+ format_error_context(buf, frame->closure->function->source, stacktrace, offset);
else
- xasprintf(&msg, "At offset %zu", (frame->ip - chunk->entries) - 1);
+ ucv_stringbuf_printf(buf, "At offset %zu", (frame->ip - chunk->entries) - 1);
- json_object_object_add(json_object_array_get_idx(stacktrace, 0), "context", xjs_new_string(msg));
-
- free(msg);
+ ucv_object_add(ucv_array_get(stacktrace, 0), "context", ucv_stringbuf_finish(buf));
return stacktrace;
}
@@ -823,7 +863,7 @@ uc_vm_raise_exception(uc_vm *vm, uc_exception_type_t type, const char *fmt, ...)
xvasprintf(&vm->exception.message, fmt, ap);
va_end(ap);
- uc_value_put(vm->exception.stacktrace);
+ ucv_put(vm->exception.stacktrace);
vm->exception.stacktrace = uc_vm_get_error_context(vm);
}
@@ -837,15 +877,15 @@ uc_vm_insn_load(uc_vm *vm, enum insn_type insn)
break;
case I_LOAD8:
- uc_vm_stack_push(vm, xjs_new_int64(vm->arg.s8));
+ uc_vm_stack_push(vm, ucv_int64_new(vm->arg.s8));
break;
case I_LOAD16:
- uc_vm_stack_push(vm, xjs_new_int64(vm->arg.s16));
+ uc_vm_stack_push(vm, ucv_int64_new(vm->arg.s16));
break;
case I_LOAD32:
- uc_vm_stack_push(vm, xjs_new_int64(vm->arg.s32));
+ uc_vm_stack_push(vm, ucv_int64_new(vm->arg.s32));
break;
default:
@@ -856,33 +896,33 @@ uc_vm_insn_load(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_load_regexp(uc_vm *vm, enum insn_type insn)
{
+ uc_value_t *re, *jstr = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
bool icase = false, newline = false, global = false;
- json_object *jstr = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
- const char *str;
- uc_regexp *re;
- char *err;
+ char *str, *err = NULL;
- if (!json_object_is_type(jstr, json_type_string) || json_object_get_string_len(jstr) < 2) {
+ if (ucv_type(jstr) != UC_STRING || ucv_string_length(jstr) < 2) {
uc_vm_stack_push(vm, NULL);
- uc_value_put(jstr);
+ ucv_put(jstr);
return;
}
- str = json_object_get_string(jstr);
+ str = ucv_string_get(jstr);
global = (*str & (1 << 0));
icase = (*str & (1 << 1));
newline = (*str & (1 << 2));
- re = uc_regexp_new(++str, icase, newline, global, &err);
+ re = ucv_regexp_new(++str, icase, newline, global, &err);
- uc_value_put(jstr);
+ ucv_put(jstr);
if (re)
- uc_vm_stack_push(vm, re->header.jso);
+ uc_vm_stack_push(vm, re);
else
uc_vm_raise_exception(vm, EXCEPTION_SYNTAX, "%s", err);
+
+ free(err);
}
static void
@@ -894,29 +934,32 @@ uc_vm_insn_load_null(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_load_bool(uc_vm *vm, enum insn_type insn)
{
- uc_vm_stack_push(vm, xjs_new_boolean(insn == I_LTRUE));
+ uc_vm_stack_push(vm, ucv_boolean_new(insn == I_LTRUE));
}
static void
uc_vm_insn_load_var(uc_vm *vm, enum insn_type insn)
{
- json_object *name, *val = NULL;
- uc_prototype *scope, *next;
+ uc_value_t *name, *val = NULL;
+ uc_value_t *scope, *next;
+ bool found;
scope = vm->globals;
name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
- while (json_object_get_type(name) == json_type_string) {
- if (json_object_object_get_ex(scope->header.jso, json_object_get_string(name), &val))
+ while (ucv_type(name) == UC_STRING) {
+ val = ucv_object_get(scope, ucv_string_get(name), &found);
+
+ if (found)
break;
- next = scope->parent;
+ next = ucv_prototype_get(scope);
if (!next) {
if (vm->config->strict_declarations) {
uc_vm_raise_exception(vm, EXCEPTION_REFERENCE,
"access to undeclared variable %s",
- json_object_get_string(name));
+ ucv_string_get(name));
}
break;
@@ -925,21 +968,21 @@ uc_vm_insn_load_var(uc_vm *vm, enum insn_type insn)
scope = next;
}
- uc_value_put(name);
+ ucv_put(name);
- uc_vm_stack_push(vm, uc_value_get(val));
+ uc_vm_stack_push(vm, ucv_get(val));
}
static void
uc_vm_insn_load_val(uc_vm *vm, enum insn_type insn)
{
- json_object *k = uc_vm_stack_pop(vm);
- json_object *v = uc_vm_stack_pop(vm);
+ uc_value_t *k = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
- switch (json_object_get_type(v)) {
- case json_type_object:
- case json_type_array:
- uc_vm_stack_push(vm, uc_getval(v, k));
+ switch (ucv_type(v)) {
+ case UC_OBJECT:
+ case UC_ARRAY:
+ uc_vm_stack_push(vm, uc_getval(vm, v, k));
break;
default:
@@ -950,21 +993,20 @@ uc_vm_insn_load_val(uc_vm *vm, enum insn_type insn)
break;
}
-
- uc_value_put(k);
- uc_value_put(v);
+ ucv_put(k);
+ ucv_put(v);
}
static void
uc_vm_insn_load_upval(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- uc_upvalref *ref = frame->closure->upvals[vm->arg.u32];
+ uc_upvalref_t *ref = frame->closure->upvals[vm->arg.u32];
if (ref->closed)
- uc_vm_stack_push(vm, uc_value_get(ref->value));
+ uc_vm_stack_push(vm, ucv_get(ref->value));
else
- uc_vm_stack_push(vm, uc_value_get(vm->stack.entries[ref->slot]));
+ uc_vm_stack_push(vm, ucv_get(vm->stack.entries[ref->slot]));
}
static void
@@ -972,15 +1014,16 @@ uc_vm_insn_load_local(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- uc_vm_stack_push(vm, uc_value_get(vm->stack.entries[frame->stackframe + vm->arg.u32]));
+ uc_vm_stack_push(vm, ucv_get(vm->stack.entries[frame->stackframe + vm->arg.u32]));
}
-static uc_upvalref *
+static uc_upvalref_t *
uc_vm_capture_upval(uc_vm *vm, size_t slot)
{
- uc_upvalref *curr = vm->open_upvals;
- uc_upvalref *prev = NULL;
- uc_upvalref *created;
+ uc_upvalref_t *curr = vm->open_upvals;
+ uc_upvalref_t *prev = NULL;
+ uc_upvalref_t *created;
+ char *s;
while (curr && curr->slot > slot) {
prev = curr;
@@ -988,23 +1031,23 @@ uc_vm_capture_upval(uc_vm *vm, size_t slot)
}
if (curr && curr->slot == slot) {
- if (vm->trace)
- fprintf(stderr, " {+%zu} <%p> %s\n",
- slot,
- curr,
- json_object_to_json_string(vm->stack.entries[slot]));
+ if (vm->trace) {
+ s = ucv_to_string(NULL, vm->stack.entries[slot]);
+ fprintf(stderr, " {+%zu} <%p> %s\n", slot, curr, s);
+ free(s);
+ }
return curr;
}
- created = uc_upvalref_new(slot);
+ created = (uc_upvalref_t *)ucv_upvalref_new(slot);
created->next = curr;
- if (vm->trace)
- fprintf(stderr, " {*%zu} <%p> %s\n",
- slot,
- created,
- json_object_to_json_string(vm->stack.entries[slot]));
+ if (vm->trace) {
+ s = ucv_to_string(NULL, vm->stack.entries[slot]);
+ fprintf(stderr, " {*%zu} <%p> %s\n", slot, created, s);
+ free(s);
+ }
if (prev)
prev->next = created;
@@ -1017,21 +1060,22 @@ uc_vm_capture_upval(uc_vm *vm, size_t slot)
static void
uc_vm_close_upvals(uc_vm *vm, size_t slot)
{
- uc_upvalref *ref;
+ uc_upvalref_t *ref;
+ char *s;
while (vm->open_upvals && vm->open_upvals->slot >= slot) {
ref = vm->open_upvals;
- ref->value = uc_value_get(vm->stack.entries[ref->slot]);
+ ref->value = ucv_get(vm->stack.entries[ref->slot]);
ref->closed = true;
- if (vm->trace)
- fprintf(stderr, " {!%zu} <%p> %s\n",
- ref->slot,
- ref,
- json_object_to_json_string(ref->value));
+ if (vm->trace) {
+ s = ucv_to_string(NULL, ref->value);
+ fprintf(stderr, " {!%zu} <%p> %s\n", ref->slot, ref, s);
+ free(s);
+ }
vm->open_upvals = ref->next;
- json_object_put(ref->header.jso);
+ ucv_put(&ref->header);
}
}
@@ -1039,13 +1083,13 @@ static void
uc_vm_insn_load_closure(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- json_object *fno = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
- uc_function *function = uc_object_as_function(fno);
- uc_closure *closure = uc_closure_new(function, insn == I_ARFN);
+ uc_value_t *fno = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
+ uc_function_t *function = (uc_function_t *)fno;
+ uc_closure_t *closure = (uc_closure_t *)ucv_closure_new(vm, function, insn == I_ARFN);
volatile int32_t uv;
size_t i;
- uc_vm_stack_push(vm, closure->header.jso);
+ uc_vm_stack_push(vm, &closure->header);
for (i = 0; i < function->nupvals; i++) {
uv = (
@@ -1060,7 +1104,7 @@ uc_vm_insn_load_closure(uc_vm *vm, enum insn_type insn)
else
closure->upvals[i] = frame->closure->upvals[uv];
- uc_value_get(closure->upvals[i]->header.jso);
+ ucv_get(&closure->upvals[i]->header);
frame->ip += 4;
}
@@ -1069,23 +1113,26 @@ uc_vm_insn_load_closure(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_store_var(uc_vm *vm, enum insn_type insn)
{
- json_object *name, *v = uc_vm_stack_pop(vm);
- uc_prototype *scope, *next;
+ uc_value_t *name, *v = uc_vm_stack_pop(vm);
+ uc_value_t *scope, *next;
+ bool found;
scope = vm->globals;
name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32);
- while (json_object_get_type(name) == json_type_string) {
- if (json_object_object_get_ex(scope->header.jso, json_object_get_string(name), NULL))
+ while (ucv_type(name) == UC_STRING) {
+ ucv_object_get(scope, ucv_string_get(name), &found);
+
+ if (found)
break;
- next = scope->parent;
+ next = ucv_prototype_get(scope);
if (!next) {
if (vm->config->strict_declarations) {
uc_vm_raise_exception(vm, EXCEPTION_REFERENCE,
"access to undeclared variable %s",
- json_object_get_string(name));
+ ucv_string_get(name));
}
break;
@@ -1094,53 +1141,45 @@ uc_vm_insn_store_var(uc_vm *vm, enum insn_type insn)
scope = next;
}
- if (scope && json_object_get_type(name) == json_type_string)
- json_object_object_add(scope->header.jso, json_object_get_string(name), uc_value_get(v));
+ if (scope && ucv_type(name) == UC_STRING)
+ ucv_object_add(scope, ucv_string_get(name), ucv_get(v));
- uc_value_put(name);
+ ucv_put(name);
uc_vm_stack_push(vm, v);
}
static void
uc_vm_insn_store_val(uc_vm *vm, enum insn_type insn)
{
- json_object *v = uc_vm_stack_pop(vm);
- json_object *k = uc_vm_stack_pop(vm);
- json_object *o = uc_vm_stack_pop(vm);
-
- const char *typenames[] = {
- [json_type_string] = "string",
- [json_type_int] = "integer",
- [json_type_double] = "double",
- [json_type_boolean] = "boolean",
- [json_type_null] = "null"
- };
+ uc_value_t *v = uc_vm_stack_pop(vm);
+ uc_value_t *k = uc_vm_stack_pop(vm);
+ uc_value_t *o = uc_vm_stack_pop(vm);
- switch (json_object_get_type(o)) {
- case json_type_object:
- case json_type_array:
- uc_vm_stack_push(vm, uc_setval(o, k, v));
+ switch (ucv_type(o)) {
+ case UC_OBJECT:
+ case UC_ARRAY:
+ uc_vm_stack_push(vm, uc_setval(vm, o, k, v));
break;
default:
uc_vm_raise_exception(vm, EXCEPTION_TYPE,
"attempt to set property on %s value",
- typenames[json_object_get_type(o)]);
+ ucv_typename(o));
}
- uc_value_put(o);
- uc_value_put(k);
+ ucv_put(o);
+ ucv_put(k);
}
static void
uc_vm_insn_store_upval(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- uc_upvalref *ref = frame->closure->upvals[vm->arg.u32];
- json_object *val = uc_value_get(uc_vm_stack_peek(vm, 0));
+ uc_upvalref_t *ref = frame->closure->upvals[vm->arg.u32];
+ uc_value_t *val = ucv_get(uc_vm_stack_peek(vm, 0));
if (ref->closed) {
- uc_value_put(ref->value);
+ ucv_put(ref->value);
ref->value = val;
}
else {
@@ -1152,43 +1191,43 @@ static void
uc_vm_insn_store_local(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- json_object *val = uc_value_get(uc_vm_stack_peek(vm, 0));
+ uc_value_t *val = ucv_get(uc_vm_stack_peek(vm, 0));
uc_vm_stack_set(vm, frame->stackframe + vm->arg.u32, val);
}
-static json_object *
-uc_vm_value_bitop(uc_vm *vm, enum insn_type operation, json_object *value, json_object *operand)
+static uc_value_t *
+uc_vm_value_bitop(uc_vm *vm, enum insn_type operation, uc_value_t *value, uc_value_t *operand)
{
- json_object *rv = NULL;
+ uc_value_t *rv = NULL;
int64_t n1, n2;
double d;
- if (uc_cast_number(value, &n1, &d) == json_type_double)
+ if (uc_cast_number(value, &n1, &d) == UC_DOUBLE)
n1 = isnan(d) ? 0 : (int64_t)d;
- if (uc_cast_number(operand, &n2, &d) == json_type_double)
+ if (uc_cast_number(operand, &n2, &d) == UC_DOUBLE)
n2 = isnan(d) ? 0 : (int64_t)d;
switch (operation) {
case I_LSHIFT:
- rv = xjs_new_int64(n1 << n2);
+ rv = ucv_int64_new(n1 << n2);
break;
case I_RSHIFT:
- rv = xjs_new_int64(n1 >> n2);
+ rv = ucv_int64_new(n1 >> n2);
break;
case I_BAND:
- rv = xjs_new_int64(n1 & n2);
+ rv = ucv_int64_new(n1 & n2);
break;
case I_BXOR:
- rv = xjs_new_int64(n1 ^ n2);
+ rv = ucv_int64_new(n1 ^ n2);
break;
case I_BOR:
- rv = xjs_new_int64(n1 | n2);
+ rv = ucv_int64_new(n1 | n2);
break;
default:
@@ -1198,32 +1237,32 @@ uc_vm_value_bitop(uc_vm *vm, enum insn_type operation, json_object *value, json_
return rv;
}
-static json_object *
-uc_vm_value_arith(uc_vm *vm, enum insn_type operation, json_object *value, json_object *operand)
+static uc_value_t *
+uc_vm_value_arith(uc_vm *vm, enum insn_type operation, uc_value_t *value, uc_value_t *operand)
{
- json_object *rv = NULL;
- enum json_type t1, t2;
- const char *s1, *s2;
+ uc_value_t *rv = NULL;
+ uc_type_t t1, t2;
+ char *s, *s1, *s2;
size_t len1, len2;
int64_t n1, n2;
double d1, d2;
- char *s;
if (operation > I_MOD)
return uc_vm_value_bitop(vm, operation, value, operand);
- if (operation == I_ADD &&
- (json_object_is_type(value, json_type_string) ||
- json_object_is_type(operand, json_type_string))) {
- s1 = value ? json_object_get_string(value) : "null";
- s2 = operand ? json_object_get_string(operand) : "null";
- len1 = strlen(s1);
- len2 = strlen(s2);
+ if (operation == I_ADD && (ucv_type(value) == UC_STRING || ucv_type(operand) == UC_STRING)) {
+ s1 = (ucv_type(value) != UC_STRING) ? ucv_to_string(vm, value) : NULL;
+ s2 = (ucv_type(operand) != UC_STRING) ? ucv_to_string(vm, operand) : NULL;
+ len1 = s1 ? strlen(s1) : ucv_string_length(value);
+ len2 = s2 ? strlen(s2) : ucv_string_length(operand);
s = xalloc(len1 + len2 + 1);
- snprintf(s, len1 + len2 + 1, "%s%s", s1, s2);
+ memcpy(s, s1 ? s1 : ucv_string_get(value), len1);
+ memcpy(s + len1, s2 ? s2 : ucv_string_get(operand), len2);
+ free(s1);
+ free(s2);
- rv = xjs_new_string(s);
+ rv = ucv_string_new_length(s, len1 + len2);
free(s);
@@ -1233,38 +1272,38 @@ uc_vm_value_arith(uc_vm *vm, enum insn_type operation, json_object *value, json_
t1 = uc_cast_number(value, &n1, &d1);
t2 = uc_cast_number(operand, &n2, &d2);
- if (t1 == json_type_double || t2 == json_type_double) {
- d1 = (t1 == json_type_double) ? d1 : (double)n1;
- d2 = (t2 == json_type_double) ? d2 : (double)n2;
+ if (t1 == UC_DOUBLE || t2 == UC_DOUBLE) {
+ d1 = (t1 == UC_DOUBLE) ? d1 : (double)n1;
+ d2 = (t2 == UC_DOUBLE) ? d2 : (double)n2;
switch (operation) {
case I_ADD:
case I_PLUS:
- rv = uc_double_new(d1 + d2);
+ rv = ucv_double_new(d1 + d2);
break;
case I_SUB:
- rv = uc_double_new(d1 - d2);
+ rv = ucv_double_new(d1 - d2);
break;
case I_MUL:
- rv = uc_double_new(d1 * d2);
+ rv = ucv_double_new(d1 * d2);
break;
case I_DIV:
if (d2 == 0.0)
- rv = uc_double_new(INFINITY);
+ rv = ucv_double_new(INFINITY);
else if (isnan(d2))
- rv = uc_double_new(NAN);
+ rv = ucv_double_new(NAN);
else if (!isfinite(d2))
- rv = uc_double_new(isfinite(d1) ? 0.0 : NAN);
+ rv = ucv_double_new(isfinite(d1) ? 0.0 : NAN);
else
- rv = uc_double_new(d1 / d2);
+ rv = ucv_double_new(d1 / d2);
break;
case I_MOD:
- rv = uc_double_new(NAN);
+ rv = ucv_double_new(NAN);
break;
default:
@@ -1278,27 +1317,27 @@ uc_vm_value_arith(uc_vm *vm, enum insn_type operation, json_object *value, json_
switch (operation) {
case I_ADD:
case I_PLUS:
- rv = xjs_new_int64(n1 + n2);
+ rv = ucv_int64_new(n1 + n2);
break;
case I_SUB:
- rv = xjs_new_int64(n1 - n2);
+ rv = ucv_int64_new(n1 - n2);
break;
case I_MUL:
- rv = xjs_new_int64(n1 * n2);
+ rv = ucv_int64_new(n1 * n2);
break;
case I_DIV:
if (n2 == 0)
- rv = uc_double_new(INFINITY);
+ rv = ucv_double_new(INFINITY);
else
- rv = xjs_new_int64(n1 / n2);
+ rv = ucv_int64_new(n1 / n2);
break;
case I_MOD:
- rv = xjs_new_int64(n1 % n2);
+ rv = ucv_int64_new(n1 % n2);
break;
default:
@@ -1315,25 +1354,28 @@ uc_vm_value_arith(uc_vm *vm, enum insn_type operation, json_object *value, json_
static void
uc_vm_insn_update_var(uc_vm *vm, enum insn_type insn)
{
- json_object *name, *val, *inc = uc_vm_stack_pop(vm);
- uc_prototype *scope, *next;
+ uc_value_t *name, *val, *inc = uc_vm_stack_pop(vm);
+ uc_value_t *scope, *next;
+ bool found;
scope = vm->globals;
name = uc_chunk_get_constant(uc_vm_current_chunk(vm), vm->arg.u32 & 0x00FFFFFF);
- assert(json_object_is_type(name, json_type_string));
+ assert(ucv_type(name) == UC_STRING);
+
+ while (true) {
+ val = ucv_object_get(scope, ucv_string_get(name), &found);
- while (true) {
- if (json_object_object_get_ex(scope->header.jso, json_object_get_string(name), &val))
+ if (found)
break;
- next = scope->parent;
+ next = ucv_prototype_get(scope);
if (!next) {
if (vm->config->strict_declarations) {
uc_vm_raise_exception(vm, EXCEPTION_REFERENCE,
"access to undeclared variable %s",
- json_object_get_string(name));
+ ucv_string_get(name));
}
break;
@@ -1344,26 +1386,26 @@ uc_vm_insn_update_var(uc_vm *vm, enum insn_type insn)
val = uc_vm_value_arith(vm, vm->arg.u32 >> 24, val, inc);
- json_object_object_add(scope->header.jso, json_object_get_string(name), uc_value_get(val));
+ ucv_object_add(scope, ucv_string_get(name), ucv_get(val));
uc_vm_stack_push(vm, val);
- uc_value_put(name);
- uc_value_put(inc);
+ ucv_put(name);
+ ucv_put(inc);
}
static void
uc_vm_insn_update_val(uc_vm *vm, enum insn_type insn)
{
- json_object *inc = uc_vm_stack_pop(vm);
- json_object *k = uc_vm_stack_pop(vm);
- json_object *v = uc_vm_stack_pop(vm);
- json_object *val = NULL;
+ uc_value_t *inc = uc_vm_stack_pop(vm);
+ uc_value_t *k = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
+ uc_value_t *val = NULL;
- switch (json_object_get_type(v)) {
- case json_type_object:
- case json_type_array:
- val = uc_getval(v, k);
- uc_vm_stack_push(vm, uc_setval(v, k, uc_vm_value_arith(vm, vm->arg.u8, val, inc)));
+ switch (ucv_type(v)) {
+ case UC_OBJECT:
+ case UC_ARRAY:
+ val = uc_getval(vm, v, k);
+ uc_vm_stack_push(vm, uc_setval(vm, v, k, uc_vm_value_arith(vm, vm->arg.u8, val, inc)));
break;
default:
@@ -1374,10 +1416,10 @@ uc_vm_insn_update_val(uc_vm *vm, enum insn_type insn)
break;
}
- uc_value_put(val);
- uc_value_put(inc);
- uc_value_put(v);
- uc_value_put(k);
+ ucv_put(val);
+ ucv_put(inc);
+ ucv_put(v);
+ ucv_put(k);
}
static void
@@ -1385,9 +1427,9 @@ uc_vm_insn_update_upval(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
size_t slot = vm->arg.u32 & 0x00FFFFFF;
- uc_upvalref *ref = frame->closure->upvals[slot];
- json_object *inc = uc_vm_stack_pop(vm);
- json_object *val;
+ uc_upvalref_t *ref = frame->closure->upvals[slot];
+ uc_value_t *inc = uc_vm_stack_pop(vm);
+ uc_value_t *val;
if (ref->closed)
val = ref->value;
@@ -1398,14 +1440,14 @@ uc_vm_insn_update_upval(uc_vm *vm, enum insn_type insn)
uc_vm_stack_push(vm, val);
- uc_value_put(inc);
+ ucv_put(inc);
if (ref->closed) {
- uc_value_put(ref->value);
- ref->value = uc_value_get(uc_vm_stack_peek(vm, 0));
+ ucv_put(ref->value);
+ ref->value = ucv_get(uc_vm_stack_peek(vm, 0));
}
else {
- uc_vm_stack_set(vm, ref->slot, uc_value_get(uc_vm_stack_peek(vm, 0)));
+ uc_vm_stack_set(vm, ref->slot, ucv_get(uc_vm_stack_peek(vm, 0)));
}
}
@@ -1414,22 +1456,22 @@ uc_vm_insn_update_local(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
size_t slot = vm->arg.u32 & 0x00FFFFFF;
- json_object *inc = uc_vm_stack_pop(vm);
- json_object *val;
+ uc_value_t *inc = uc_vm_stack_pop(vm);
+ uc_value_t *val;
val = uc_vm_value_arith(vm, vm->arg.u32 >> 24,
vm->stack.entries[frame->stackframe + slot], inc);
uc_vm_stack_push(vm, val);
- uc_value_put(inc);
- uc_vm_stack_set(vm, frame->stackframe + slot, uc_value_get(uc_vm_stack_peek(vm, 0)));
+ ucv_put(inc);
+ uc_vm_stack_set(vm, frame->stackframe + slot, ucv_get(uc_vm_stack_peek(vm, 0)));
}
static void
uc_vm_insn_narr(uc_vm *vm, enum insn_type insn)
{
- json_object *arr = xjs_new_array_size(vm->arg.u32);
+ uc_value_t *arr = ucv_array_new_length(vm, vm->arg.u32);
uc_vm_stack_push(vm, arr);
}
@@ -1437,11 +1479,11 @@ uc_vm_insn_narr(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_parr(uc_vm *vm, enum insn_type insn)
{
- json_object *arr = uc_vm_stack_peek(vm, vm->arg.u32);
+ uc_value_t *arr = uc_vm_stack_peek(vm, vm->arg.u32);
size_t idx;
for (idx = 0; idx < vm->arg.u32; idx++)
- json_object_array_add(arr, uc_vm_stack_peek(vm, vm->arg.u32 - idx - 1));
+ ucv_array_push(arr, uc_vm_stack_peek(vm, vm->arg.u32 - idx - 1));
for (idx = 0; idx < vm->arg.u32; idx++)
uc_vm_stack_pop(vm);
@@ -1452,79 +1494,81 @@ uc_vm_insn_parr(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_marr(uc_vm *vm, enum insn_type insn)
{
- json_object *src = uc_vm_stack_pop(vm);
- json_object *dst = uc_vm_stack_peek(vm, 0);
+ uc_value_t *src = uc_vm_stack_pop(vm);
+ uc_value_t *dst = uc_vm_stack_peek(vm, 0);
size_t i;
+ char *s;
- if (!json_object_is_type(src, json_type_array)) {
- uc_vm_raise_exception(vm, EXCEPTION_TYPE,
- "(%s) is not iterable",
- json_object_to_json_string(src));
+ if (ucv_type(src) != UC_ARRAY) {
+ s = ucv_to_string(vm, src);
+ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "(%s) is not iterable", s);
+ ucv_put(src);
+ free(s);
return;
}
- for (i = 0; i < json_object_array_length(src); i++)
- json_object_array_add(dst, uc_value_get(json_object_array_get_idx(src, i)));
+ for (i = 0; i < ucv_array_length(src); i++)
+ ucv_array_push(dst, ucv_get(ucv_array_get(src, i)));
- uc_value_put(src);
+ ucv_put(src);
}
static void
uc_vm_insn_nobj(uc_vm *vm, enum insn_type insn)
{
- json_object *arr = xjs_new_object();
+ uc_value_t *obj = ucv_object_new(vm);
- uc_vm_stack_push(vm, arr);
+ uc_vm_stack_push(vm, obj);
}
static void
uc_vm_insn_sobj(uc_vm *vm, enum insn_type insn)
{
- json_object *obj = uc_vm_stack_peek(vm, vm->arg.u32);
+ uc_value_t *obj = uc_vm_stack_peek(vm, vm->arg.u32);
size_t idx;
for (idx = 0; idx < vm->arg.u32; idx += 2) {
- json_object_object_add(obj,
- json_object_get_string(uc_vm_stack_peek(vm, vm->arg.u32 - idx - 1)),
- uc_value_get(uc_vm_stack_peek(vm, vm->arg.u32 - idx - 2)));
+ ucv_object_add(obj,
+ ucv_string_get(uc_vm_stack_peek(vm, vm->arg.u32 - idx - 1)),
+ ucv_get(uc_vm_stack_peek(vm, vm->arg.u32 - idx - 2)));
}
for (idx = 0; idx < vm->arg.u32; idx++)
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
}
static void
uc_vm_insn_mobj(uc_vm *vm, enum insn_type insn)
{
- json_object *src = uc_vm_stack_pop(vm);
- json_object *dst = uc_vm_stack_peek(vm, 0);
- char *istr;
+ uc_value_t *src = uc_vm_stack_pop(vm);
+ uc_value_t *dst = uc_vm_stack_peek(vm, 0);
size_t i;
+ char *s;
- switch (json_object_get_type(src)) {
- case json_type_object:
+ switch (ucv_type(src)) {
+ case UC_OBJECT:
; /* a label can only be part of a statement and a declaration is not a statement */
- json_object_object_foreach(src, k, v)
- json_object_object_add(dst, k, uc_value_get(v));
+ ucv_object_foreach(src, k, v)
+ ucv_object_add(dst, k, ucv_get(v));
- uc_value_put(src);
+ ucv_put(src);
break;
case json_type_array:
- for (i = 0; i < json_object_array_length(src); i++) {
- xasprintf(&istr, "%zu", i);
- json_object_object_add(dst, istr, uc_value_get(json_object_array_get_idx(src, i)));
- free(istr);
+ for (i = 0; i < ucv_array_length(src); i++) {
+ xasprintf(&s, "%zu", i);
+ ucv_object_add(dst, s, ucv_get(ucv_array_get(src, i)));
+ free(s);
}
- uc_value_put(src);
+ ucv_put(src);
break;
default:
- uc_vm_raise_exception(vm, EXCEPTION_TYPE,
- "Value (%s) is not iterable",
- json_object_to_json_string(src));
+ s = ucv_to_string(vm, src);
+ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Value (%s) is not iterable", s);
+ free(s);
break;
}
@@ -1533,14 +1577,14 @@ uc_vm_insn_mobj(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_arith(uc_vm *vm, enum insn_type insn)
{
- json_object *r2 = uc_vm_stack_pop(vm);
- json_object *r1 = uc_vm_stack_pop(vm);
- json_object *rv;
+ uc_value_t *r2 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
+ uc_value_t *rv;
rv = uc_vm_value_arith(vm, insn, r1, r2);
- uc_value_put(r1);
- uc_value_put(r2);
+ ucv_put(r1);
+ ucv_put(r2);
uc_vm_stack_push(vm, rv);
}
@@ -1548,23 +1592,23 @@ uc_vm_insn_arith(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_plus_minus(uc_vm *vm, enum insn_type insn)
{
- struct json_object *v = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
bool is_sub = (insn == I_MINUS);
- enum json_type t;
+ uc_type_t t;
int64_t n;
double d;
t = uc_cast_number(v, &n, &d);
- json_object_put(v);
+ ucv_put(v);
switch (t) {
- case json_type_int:
- uc_vm_stack_push(vm, xjs_new_int64(is_sub ? -n : n));
+ case UC_INTEGER:
+ uc_vm_stack_push(vm, ucv_int64_new(is_sub ? -n : n));
break;
default:
- uc_vm_stack_push(vm, uc_double_new(is_sub ? -d : d));
+ uc_vm_stack_push(vm, ucv_double_new(is_sub ? -d : d));
break;
}
}
@@ -1572,14 +1616,14 @@ uc_vm_insn_plus_minus(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_bitop(uc_vm *vm, enum insn_type insn)
{
- json_object *r2 = uc_vm_stack_pop(vm);
- json_object *r1 = uc_vm_stack_pop(vm);
- json_object *rv;
+ uc_value_t *r2 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
+ uc_value_t *rv;
rv = uc_vm_value_bitop(vm, insn, r1, r2);
- uc_value_put(r1);
- uc_value_put(r2);
+ ucv_put(r1);
+ ucv_put(r2);
uc_vm_stack_push(vm, rv);
}
@@ -1587,23 +1631,23 @@ uc_vm_insn_bitop(uc_vm *vm, enum insn_type insn)
static void
uc_vm_insn_complement(uc_vm *vm, enum insn_type insn)
{
- struct json_object *v = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
int64_t n;
double d;
- if (uc_cast_number(v, &n, &d) == json_type_double)
+ if (uc_cast_number(v, &n, &d) == UC_DOUBLE)
n = isnan(d) ? 0 : (int64_t)d;
- json_object_put(v);
+ ucv_put(v);
- uc_vm_stack_push(vm, xjs_new_int64(~n));
+ uc_vm_stack_push(vm, ucv_int64_new(~n));
}
static void
uc_vm_insn_rel(uc_vm *vm, enum insn_type insn)
{
- json_object *r2 = uc_vm_stack_pop(vm);
- json_object *r1 = uc_vm_stack_pop(vm);
+ uc_value_t *r2 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
bool res = false;
switch (insn) {
@@ -1627,27 +1671,27 @@ uc_vm_insn_rel(uc_vm *vm, enum insn_type insn)
break;
}
- uc_value_put(r1);
- uc_value_put(r2);
+ ucv_put(r1);
+ ucv_put(r2);
- uc_vm_stack_push(vm, xjs_new_boolean(res));
+ uc_vm_stack_push(vm, ucv_boolean_new(res));
}
static void
uc_vm_insn_in(uc_vm *vm, enum insn_type insn)
{
- json_object *r2 = uc_vm_stack_pop(vm);
- json_object *r1 = uc_vm_stack_pop(vm);
- json_object *item;
+ uc_value_t *r2 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
+ uc_value_t *item;
size_t arrlen, arridx;
bool found = false;
- const char *key;
+ char *key;
- switch (json_object_get_type(r2)) {
- case json_type_array:
- for (arridx = 0, arrlen = json_object_array_length(r2);
+ switch (ucv_type(r2)) {
+ case UC_ARRAY:
+ for (arridx = 0, arrlen = ucv_array_length(r2);
arridx < arrlen; arridx++) {
- item = json_object_array_get_idx(r2, arridx);
+ item = ucv_array_get(r2, arridx);
if (uc_cmp(TK_EQ, r1, item)) {
found = true;
@@ -1657,41 +1701,53 @@ uc_vm_insn_in(uc_vm *vm, enum insn_type insn)
break;
- case json_type_object:
- key = r1 ? json_object_get_string(r1) : "null";
- found = json_object_object_get_ex(r2, key, NULL);
+ case UC_OBJECT:
+ if (ucv_type(r1) == UC_STRING) {
+ ucv_object_get(r2, ucv_string_get(r1), &found);
+ }
+ else {
+ key = ucv_to_string(vm, r1);
+ ucv_object_get(r2, key, &found);
+ free(key);
+ }
+
break;
default:
found = false;
}
- uc_value_put(r1);
- uc_value_put(r2);
+ ucv_put(r1);
+ ucv_put(r2);
- uc_vm_stack_push(vm, xjs_new_boolean(found));
+ uc_vm_stack_push(vm, ucv_boolean_new(found));
}
static void
uc_vm_insn_equality(uc_vm *vm, enum insn_type insn)
{
- json_object *r2 = uc_vm_stack_pop(vm);
- json_object *r1 = uc_vm_stack_pop(vm);
- bool equal = uc_eq(r1, r2);
+ uc_value_t *r2 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
+ bool equal;
+
+ if (ucv_is_scalar(r1) && ucv_is_scalar(r2))
+ equal = ucv_equal(r1, r2);
+ else
+ equal = (r1 == r2);
- uc_value_put(r1);
- uc_value_put(r2);
+ ucv_put(r1);
+ ucv_put(r2);
- uc_vm_stack_push(vm, xjs_new_boolean((insn == I_EQS) ? equal : !equal));
+ uc_vm_stack_push(vm, ucv_boolean_new((insn == I_EQS) ? equal : !equal));
}
static void
uc_vm_insn_not(uc_vm *vm, enum insn_type insn)
{
- json_object *r1 = uc_vm_stack_pop(vm);
+ uc_value_t *r1 = uc_vm_stack_pop(vm);
- uc_vm_stack_push(vm, xjs_new_boolean(!uc_val_is_truish(r1)));
- uc_value_put(r1);
+ uc_vm_stack_push(vm, ucv_boolean_new(!uc_val_is_truish(r1)));
+ ucv_put(r1);
}
static void
@@ -1718,7 +1774,7 @@ uc_vm_insn_jmpz(uc_vm *vm, enum insn_type insn)
{
uc_callframe *frame = uc_vm_current_frame(vm);
uc_chunk *chunk = uc_vm_frame_chunk(frame);
- json_object *v = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
int32_t addr = vm->arg.s32;
/* ip already has been incremented */
@@ -1733,56 +1789,64 @@ uc_vm_insn_jmpz(uc_vm *vm, enum insn_type insn)
if (!uc_val_is_truish(v))
frame->ip += addr;
- uc_value_put(v);
+ ucv_put(v);
}
static void
uc_vm_insn_next(uc_vm *vm, enum insn_type insn)
{
- json_object *k = uc_vm_stack_pop(vm);
- json_object *v = uc_vm_stack_pop(vm);
+ uc_value_t *k = uc_vm_stack_pop(vm);
+ uc_value_t *v = uc_vm_stack_pop(vm);
+ void *end = (void *)~(uintptr_t)0;
+ uc_ressource_t *iterk;
struct lh_entry *curr;
- int64_t n;
+ uint64_t n;
+
+ if (k != NULL && ucv_type(k) != UC_RESSOURCE) {
+ fprintf(stderr, "Invalid iterator value\n");
+ abort();
+ }
+
+ if (k == NULL) {
+ k = ucv_ressource_new(NULL, NULL);
+ ((uc_ressource_t *)k)->type = UINT64_MAX;
+ }
- switch (json_object_get_type(v)) {
- case json_type_object:
- curr = k ? json_object_get_userdata(k) : json_object_get_object(v)->head;
+ iterk = (uc_ressource_t *)k;
- if (curr) {
- if (!k)
- k = xjs_new_string("[key]");
+ switch (ucv_type(v)) {
+ case UC_OBJECT:
+ curr = iterk->data ? iterk->data : ((uc_object_t *)v)->table->head;
- json_object_set_userdata(k, curr->next, NULL);
+ if (curr != NULL && curr != end) {
+ iterk->data = curr->next ? curr->next : end;
- uc_vm_stack_push(vm, xjs_new_string(curr->k));
+ uc_vm_stack_push(vm, ucv_string_new(curr->k));
if (insn == I_NEXTKV)
- uc_vm_stack_push(vm, uc_value_get((json_object *)curr->v));
+ uc_vm_stack_push(vm, ucv_get((uc_value_t *)curr->v));
uc_vm_stack_push(vm, k);
- uc_value_put(v);
+ ucv_put(v);
return;
}
break;
- case json_type_array:
- if (!k)
- k = xjs_new_int64(0);
-
- n = json_object_get_int64(k);
+ case UC_ARRAY:
+ n = (uintptr_t)iterk->data;
- if (json_object_is_type(k, json_type_int) && n < json_object_array_length(v)) {
- json_object_int_inc(k, 1);
+ if (n < ucv_array_length(v)) {
+ iterk->data = (void *)(n + 1);
if (insn == I_NEXTKV)
- uc_vm_stack_push(vm, xjs_new_int64(n));
+ uc_vm_stack_push(vm, ucv_uint64_new(n));
- uc_vm_stack_push(vm, uc_value_get(json_object_array_get_idx(v, n)));
+ uc_vm_stack_push(vm, ucv_get(ucv_array_get(v, n)));
uc_vm_stack_push(vm, k);
- uc_value_put(v);
+ ucv_put(v);
return;
}
@@ -1799,87 +1863,83 @@ uc_vm_insn_next(uc_vm *vm, enum insn_type insn)
if (insn == I_NEXTKV)
uc_vm_stack_push(vm, NULL);
- uc_value_put(k);
- uc_value_put(v);
+ ucv_put(k);
+ ucv_put(v);
}
static void
uc_vm_insn_close_upval(uc_vm *vm, enum insn_type insn)
{
uc_vm_close_upvals(vm, vm->stack.count - 1);
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
}
static void
uc_vm_insn_call(uc_vm *vm, enum insn_type insn)
{
- json_object *fno = uc_value_get(uc_vm_stack_peek(vm, vm->arg.u32 & 0xffff));
- json_object *ctx = NULL;
+ uc_value_t *fno = ucv_get(uc_vm_stack_peek(vm, vm->arg.u32 & 0xffff));
+ uc_value_t *ctx = NULL;
- if (!uc_object_is_type(fno, UC_OBJ_CLOSURE) || !uc_object_as_closure(fno)->is_arrow)
+ if (!ucv_is_arrowfn(fno))
ctx = NULL;
else if (vm->callframes.count > 0)
- ctx = uc_value_get(uc_vm_current_frame(vm)->ctx);
+ ctx = uc_vm_current_frame(vm)->ctx;
- uc_vm_call_function(vm, ctx, fno, false, vm->arg.u32);
+ uc_vm_call_function(vm, ucv_get(ctx), fno, false, vm->arg.u32);
}
static void
uc_vm_insn_mcall(uc_vm *vm, enum insn_type insn)
{
size_t key_slot = vm->stack.count - (vm->arg.u32 & 0xffff) - 1;
- json_object *ctx = vm->stack.entries[key_slot - 1];
- json_object *key = vm->stack.entries[key_slot];
- json_object *fno = uc_getval(ctx, key);
+ uc_value_t *ctx = vm->stack.entries[key_slot - 1];
+ uc_value_t *key = vm->stack.entries[key_slot];
+ uc_value_t *fno = uc_getval(vm, ctx, key);
uc_vm_stack_set(vm, key_slot, fno);
/* arrow functions as method calls inherit the parent ctx */
- if (uc_object_is_type(fno, UC_OBJ_CLOSURE) && uc_object_as_closure(fno)->is_arrow)
+ if (ucv_is_arrowfn(fno))
ctx = uc_vm_current_frame(vm)->ctx;
- uc_vm_call_function(vm, uc_value_get(ctx), uc_value_get(fno), true, vm->arg.u32);
+ uc_vm_call_function(vm, ucv_get(ctx), ucv_get(fno), true, vm->arg.u32);
}
static void
uc_vm_insn_print(uc_vm *vm, enum insn_type insn)
{
- json_object *v = uc_vm_stack_pop(vm);
- const char *p;
- size_t len;
+ uc_value_t *v = uc_vm_stack_pop(vm);
+ char *p;
- switch (json_object_get_type(v)) {
- case json_type_object:
- case json_type_array:
- p = json_object_to_json_string_ext(v, JSON_C_TO_STRING_NOSLASHESCAPE|JSON_C_TO_STRING_SPACED);
- len = strlen(p);
+ switch (ucv_type(v)) {
+ case UC_OBJECT:
+ case UC_ARRAY:
+ p = ucv_to_jsonstring(vm, v);
+ fwrite(p, 1, strlen(p), stdout);
+ free(p);
break;
- case json_type_string:
- p = json_object_get_string(v);
- len = json_object_get_string_len(v);
+ case UC_STRING:
+ fwrite(ucv_string_get(v), 1, ucv_string_length(v), stdout);
break;
- case json_type_null:
- p = "";
- len = 0;
+ case UC_NULL:
break;
default:
- p = json_object_get_string(v);
- len = strlen(p);
+ p = ucv_to_string(vm, v);
+ fwrite(p, 1, strlen(p), stdout);
+ free(p);
}
- fwrite(p, 1, len, stdout);
-
- uc_value_put(v);
+ ucv_put(v);
}
-static json_object *
+static uc_value_t *
uc_vm_callframe_pop(uc_vm *vm)
{
uc_callframe *frame = uc_vm_current_frame(vm);
- json_object *retval;
+ uc_value_t *retval;
/* close upvalues */
uc_vm_close_upvals(vm, frame->stackframe);
@@ -1891,18 +1951,18 @@ uc_vm_callframe_pop(uc_vm *vm)
/* reset function stack frame */
while (vm->stack.count > frame->stackframe)
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
/* for method calls, release context as well */
if (frame->mcall)
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
/* release function */
- uc_value_put(frame->closure ? frame->closure->header.jso : NULL);
- uc_value_put(frame->cfunction ? frame->cfunction->header.jso : NULL);
+ ucv_put((uc_value_t *)frame->closure);
+ ucv_put((uc_value_t *)frame->cfunction);
/* release context */
- uc_value_put(frame->ctx);
+ ucv_put(frame->ctx);
vm->callframes.count--;
@@ -1920,9 +1980,9 @@ uc_vm_output_exception(uc_vm *vm)
vm->exception.message);
fprintf(stderr, "%s\n\n",
- json_object_get_string(
- json_object_object_get(
- json_object_array_get_idx(vm->exception.stacktrace, 0), "context")));
+ ucv_string_get(
+ ucv_object_get(
+ ucv_array_get(vm->exception.stacktrace, 0), "context", NULL)));
}
static uc_vm_status_t
@@ -1930,7 +1990,7 @@ uc_vm_execute_chunk(uc_vm *vm)
{
uc_callframe *frame = uc_vm_current_frame(vm);
uc_chunk *chunk = uc_vm_frame_chunk(frame);
- json_object *retval;
+ uc_value_t *retval;
enum insn_type insn;
while (chunk) {
@@ -1961,7 +2021,7 @@ uc_vm_execute_chunk(uc_vm *vm)
break;
case I_LTHIS:
- uc_vm_stack_push(vm, uc_value_get(frame->ctx));
+ uc_vm_stack_push(vm, ucv_get(frame->ctx));
break;
case I_LVAR:
@@ -2100,11 +2160,11 @@ uc_vm_execute_chunk(uc_vm *vm)
break;
case I_COPY:
- uc_vm_stack_push(vm, uc_value_get(uc_vm_stack_peek(vm, vm->arg.u8)));
+ uc_vm_stack_push(vm, ucv_get(uc_vm_stack_peek(vm, vm->arg.u8)));
break;
case I_POP:
- uc_value_put(uc_vm_stack_pop(vm));
+ ucv_put(uc_vm_stack_pop(vm));
break;
case I_CUPV:
@@ -2127,7 +2187,7 @@ uc_vm_execute_chunk(uc_vm *vm)
retval = uc_vm_callframe_pop(vm);
if (vm->callframes.count == 0) {
- uc_value_put(retval);
+ ucv_put(retval);
return STATUS_OK;
}
@@ -2163,7 +2223,7 @@ uc_vm_execute_chunk(uc_vm *vm)
return ERROR_RUNTIME;
/* no exception handler in current function, pop callframe */
- uc_value_put(uc_vm_callframe_pop(vm));
+ ucv_put(uc_vm_callframe_pop(vm));
/* resume execution at topmost remaining callframe */
frame = uc_vector_last(&vm->callframes);
@@ -2176,25 +2236,25 @@ uc_vm_execute_chunk(uc_vm *vm)
}
static uc_vm_status_t
-uc_vm_preload(uc_vm *vm, json_object *modules)
+uc_vm_preload(uc_vm *vm, uc_value_t *modules)
{
- json_object *requirefn, *module, *name;
+ uc_value_t *requirefn, *module, *name;
uc_exception_type_t ex;
size_t i;
- if (!json_object_is_type(modules, json_type_array))
+ if (ucv_type(modules) != UC_ARRAY)
return STATUS_OK;
- requirefn = uc_prototype_lookup(vm->globals, "require");
+ requirefn = ucv_property_get(vm->globals, "require");
- if (!uc_object_is_type(requirefn, UC_OBJ_CFUNCTION))
+ if (ucv_type(requirefn) != UC_CFUNCTION)
return STATUS_OK;
- for (i = 0; i < json_object_array_length(modules); i++) {
- name = json_object_array_get_idx(modules, i);
+ for (i = 0; i < ucv_array_length(modules); i++) {
+ name = ucv_array_get(modules, i);
- uc_vm_stack_push(vm, uc_value_get(requirefn));
- uc_vm_stack_push(vm, uc_value_get(name));
+ uc_vm_stack_push(vm, ucv_get(requirefn));
+ uc_vm_stack_push(vm, ucv_get(name));
ex = uc_vm_call(vm, false, 1);
@@ -2203,21 +2263,22 @@ uc_vm_preload(uc_vm *vm, json_object *modules)
module = uc_vm_stack_pop(vm);
- uc_value_put(uc_setval(vm->globals->header.jso, name, module));
+ ucv_put(uc_setval(vm, vm->globals, name, module));
}
return STATUS_OK;
}
uc_vm_status_t
-uc_vm_execute(uc_vm *vm, uc_function *fn, uc_prototype *globals, json_object *modules)
+uc_vm_execute(uc_vm *vm, uc_function_t *fn, uc_value_t *globals, uc_value_t *modules)
{
- uc_closure *closure = uc_closure_new(fn, false);
+ uc_closure_t *closure = (uc_closure_t *)ucv_closure_new(vm, fn, false);
uc_callframe *frame;
+ uc_stringbuf_t *buf;
uc_vm_status_t rv;
vm->globals = globals;
- uc_value_get(globals ? globals->header.jso : NULL);
+ ucv_get(globals);
uc_vector_grow(&vm->callframes);
@@ -2227,14 +2288,12 @@ uc_vm_execute(uc_vm *vm, uc_function *fn, uc_prototype *globals, json_object *mo
frame->ip = uc_vm_frame_chunk(frame)->entries;
if (vm->trace) {
- size_t msglen = 0;
- char *msg = NULL;
+ buf = xprintbuf_new();
- format_source_context(&msg, &msglen,
- fn->source, 0, true);
+ format_source_context(buf, fn->source, 0, true);
- fprintf(stderr, "%s", msg);
- free(msg);
+ fwrite(buf->buf, 1, printbuf_length(buf), stderr);
+ printbuf_free(buf);
uc_vm_frame_dump(vm, frame);
}
@@ -2249,7 +2308,7 @@ uc_vm_execute(uc_vm *vm, uc_function *fn, uc_prototype *globals, json_object *mo
else
rv = uc_vm_execute_chunk(vm);
- uc_value_put(vm->globals->header.jso);
+ ucv_put(vm->globals);
vm->globals = NULL;
return rv;
@@ -2258,11 +2317,11 @@ uc_vm_execute(uc_vm *vm, uc_function *fn, uc_prototype *globals, json_object *mo
uc_exception_type_t
uc_vm_call(uc_vm *vm, bool mcall, size_t nargs)
{
- json_object *ctx = mcall ? uc_value_get(uc_vm_stack_peek(vm, nargs - 1)) : NULL;
- json_object *fno = uc_value_get(uc_vm_stack_peek(vm, nargs));
+ uc_value_t *ctx = mcall ? ucv_get(uc_vm_stack_peek(vm, nargs + 1)) : NULL;
+ uc_value_t *fno = ucv_get(uc_vm_stack_peek(vm, nargs));
if (uc_vm_call_function(vm, ctx, fno, mcall, nargs & 0xffff)) {
- if (!uc_object_is_type(fno, UC_OBJ_CFUNCTION))
+ if (ucv_type(fno) != UC_CFUNCTION)
uc_vm_execute_chunk(vm);
}