Skip to content

Commit

Permalink
Switch to throw/handle_exception instead of assert.
Browse files Browse the repository at this point in the history
  • Loading branch information
arlaneenalra committed May 26, 2019
1 parent a2cdbdc commit ca4feef
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 169 deletions.
2 changes: 1 addition & 1 deletion lib/byte-vectors.scm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
(bytevector-fill! (make-bytevector-prim (car args))
(if (eq? 2 (length args))
(car (cdr args))
'())))
0)))

;; Create a vector from an arbitrary list of arguments.
(define (bytevector . args)
Expand Down
4 changes: 2 additions & 2 deletions src/libinsomniac_bootstrap/scheme.y
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%pure-parser
/* %define api.pure */
/* %pure-parser */
%define api.pure

%{
#include "bootstrap_internal.h"
Expand Down
1 change: 1 addition & 0 deletions src/libinsomniac_vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_library(insomniac_vm
vm_output.c
vm_alloc.c
vm_env.c
vm_exception.c
)

target_link_libraries(insomniac_vm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ void op_lit_string(vm_internal_type *vm) {
void op_make_symbol(vm_internal_type *vm) {
vm->reg1 = vm_pop(vm);

assert(vm->reg1 && vm->reg1->type == STRING);
if (vm->reg1->type != STRING) {
throw(vm, "Only string can be converted into a symbol.", 1, vm->reg1);
}

make_symbol(vm, &vm->reg1);

Expand Down
17 changes: 6 additions & 11 deletions src/libinsomniac_vm/libinsomniac_vm_instructions/vm_logic.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "vm_instructions_internal.h"

/* does a simple object equivalence check */
/* Does a simple object equivalence check. */
void op_eq(vm_internal_type *vm) {
object_type *obj1 = 0;
object_type *obj2 = 0;
Expand All @@ -9,11 +9,11 @@ void op_eq(vm_internal_type *vm) {
vm->reg1 = obj1 = vm_pop(vm);
vm->reg2 = obj2 = vm_pop(vm);

/* make sure we have actual objects */
/* Make sure we have actual objects. */
if ((!obj1 || !obj2) && (obj1->type != obj2->type)) {
vm_push(vm, vm->vm_false);
} else {
/* Do comparisons for special types */
/* Do comparisons for special types. */

switch (obj1->type) {
case FIXNUM:
Expand All @@ -33,23 +33,18 @@ void op_eq(vm_internal_type *vm) {
break;
}

/* push the result onto the stack */
/* Push the result onto the stack. */
vm_push(vm, result ? vm->vm_true : vm->vm_false);
}
}

/* return the boolean inverse of the given object */
/* Return the boolean inverse of the given object. */
void op_not(vm_internal_type *vm) {
object_type *obj = 0;

vm->reg1 = obj = vm_pop(vm);

if (!obj) {
printf("Stack Underrun!");
assert(0);
}

/* only #f is false */
/* Only #f is false. */
if (obj->type == BOOL && !obj->value.boolean) {
vm_push(vm, vm->vm_true);
} else {
Expand Down
16 changes: 4 additions & 12 deletions src/libinsomniac_vm/libinsomniac_vm_instructions/vm_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@
/* TODO: replace this with sane exception \
handler */ \
if (!num1 || num1->type != FIXNUM || !num2 || num2->type != FIXNUM) { \
printf("Attempt to calculate with non-number\n"); \
output_object(stdout, num1); \
printf("\n"); \
output_object(stdout, num2); \
assert(0); \
throw(vm, "Attempt to calculate with non-number\n", 2, num1, num2); \
return; \
} \
\
vm->reg3 = result = vm_alloc(vm, FIXNUM); \
Expand All @@ -41,13 +38,8 @@
/* TODO: replace this with sane exception \
handler */ \
if (!num1 || num1->type != FIXNUM || !num2 || num2->type != FIXNUM) { \
printf("Attempt to compare with non-number\n"); \
printf("\""); \
output_object(stdout, num1); \
printf("\"\n\""); \
output_object(stdout, num2); \
printf("\"\n"); \
assert(0); \
throw(vm, "Attempt to compare with non-number\n", 2, num1, num2); \
return; \
} \
\
if (num1->value.integer op num2->value.integer) { \
Expand Down
114 changes: 77 additions & 37 deletions src/libinsomniac_vm/libinsomniac_vm_instructions/vm_vector.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#include "vm_instructions_internal.h"

/* allocate a new byte vector */
/* Allocate a new byte vector. */
void op_make_byte_vector(vm_internal_type *vm) {
object_type *obj = 0;
vm_int length = 0;

vm->reg1 = obj = vm_pop(vm);

/* make sure we have a number */
assert(obj && obj->type == FIXNUM);
/* Make sure we have a number. */
if (obj->type != FIXNUM) {
throw(vm, "Make byte vector requires a number argument.", 1, obj);
return;
}

length = obj->value.integer;

Expand All @@ -17,15 +20,18 @@ void op_make_byte_vector(vm_internal_type *vm) {
vm_push(vm, obj);
}

/* allocate a new vector */
/* Allocate a new vector. */
void op_make_vector(vm_internal_type *vm) {
object_type *obj = 0;
vm_int length = 0;

vm->reg1 = obj = vm_pop(vm);

/* make sure we have a number */
assert(obj && obj->type == FIXNUM);
/* Make sure we have a number. */
if (obj->type != FIXNUM) {
throw(vm, "Make vector requires a number argument.", 1, obj);
return;
}

length = obj->value.integer;

Expand All @@ -34,15 +40,18 @@ void op_make_vector(vm_internal_type *vm) {
vm_push(vm, obj);
}

/* allocate a new record */
/* Allocate a new record. */
void op_make_record(vm_internal_type *vm) {
object_type *obj = 0;
vm_int length = 0;

vm->reg1 = obj = vm_pop(vm);

/* make sure we have a number */
assert(obj && obj->type == FIXNUM);
/* Make sure we have a number. */
if (obj->type != FIXNUM) {
throw(vm, "Make record requires a number argument.", 1, obj);
return;
}

length = obj->value.integer;

Expand All @@ -51,15 +60,16 @@ void op_make_record(vm_internal_type *vm) {
vm_push(vm, obj);
}

/* return the lenght of a vector */
/* Return the length of a vector. */
void op_vector_length(vm_internal_type *vm) {
object_type *obj = 0;
object_type *length = 0;

vm->reg1 = obj = vm_pop(vm);

if (!obj || (obj->type != VECTOR && obj->type != BYTE_VECTOR)) {
if (obj->type != VECTOR && obj->type != BYTE_VECTOR) {
throw(vm, "Attempt to read vector length of non-vector!", 1, obj);
return;
}

vm->reg2 = length = vm_alloc(vm, FIXNUM);
Expand All @@ -68,7 +78,7 @@ void op_vector_length(vm_internal_type *vm) {
vm_push(vm, length);
}

/* set an element in a vector */
/* Set an element in a vector. */
void op_index_set(vm_internal_type *vm) {
object_type *vector = 0;
object_type *obj_index = 0;
Expand All @@ -79,26 +89,36 @@ void op_index_set(vm_internal_type *vm) {
vm->reg2 = obj = vm_pop(vm);
vm->reg3 = obj_index = vm_pop(vm);

assert(obj_index && obj_index->type == FIXNUM);
if (obj_index->type != FIXNUM) {
throw(vm, "The index must be a number.", 1, obj_index);
return;
}

index = obj_index->value.integer;

assert(
vector &&
(vector->type == VECTOR || vector->type == RECORD ||
vector->type == BYTE_VECTOR) &&
vector->value.vector.length >= index);

/* do the set */
/* Make sure we have a vector or equivalent. */
if (!((vector->type == VECTOR ||
vector->type == RECORD ||
vector->type == BYTE_VECTOR
) && vector->value.vector.length >= index)) {

throw(vm, "Set by index requires a vector.", 1, vector);
return;
}

/* Do the set. */
if (vector->type == VECTOR || vector->type == RECORD) {
vector->value.vector.vector[index] = obj;
} else {
assert(obj && obj_index->type == FIXNUM);
if (obj->type != FIXNUM) {
throw(vm, "Byte vectors may only contain numbers.", 1, obj);
return;
}
vector->value.byte_vector.vector[index] = obj->value.integer;
}
}

/* read an element from a vector */
/* Read an element from a vector. */
void op_index_ref(vm_internal_type *vm) {
object_type *vector = 0;
object_type *obj_index = 0;
Expand All @@ -108,21 +128,28 @@ void op_index_ref(vm_internal_type *vm) {
vm->reg1 = vector = vm_pop(vm);
vm->reg2 = obj_index = vm_pop(vm);

assert(obj_index && obj_index->type == FIXNUM);
if (obj_index->type != FIXNUM) {
throw(vm, "The index must be a number.", 1, obj_index);
return;
}

index = obj_index->value.integer;

assert(
vector &&
(vector->type == VECTOR || vector->type == RECORD ||
vector->type == BYTE_VECTOR) &&
vector->value.vector.length >= index);

/* do the read */
/* Make sure we have a vector or equivalent. */
if (!((vector->type == VECTOR ||
vector->type == RECORD ||
vector->type == BYTE_VECTOR
) && vector->value.vector.length >= index)) {

throw(vm, "Read by index requires a vector.", 1, vector);
return;
}

/* Do the read. */
if (vector->type == VECTOR || vector->type == RECORD) {
vm->reg3 = obj = vector->value.vector.vector[index];
} else {
/* read an integer. */
/* Read an integer. */
vm->reg3 = obj = vm_alloc(vm, FIXNUM);
obj->value.integer = vector->value.byte_vector.vector[index];
}
Expand All @@ -141,21 +168,31 @@ void op_slice(vm_internal_type *vm) {
vm->reg2 = end = vm_pop(vm);
vm->reg3 = start = vm_pop(vm);

assert(
vector && (vector->type == VECTOR || vector->type == BYTE_VECTOR) &&
vector->value.vector.length >= end->value.integer);
if (!((vector && (vector->type == VECTOR || vector->type == BYTE_VECTOR) &&
vector->value.vector.length >= end->value.integer))) {

throw(vm, "Slice must be inside the bounds of a vector.",
3, vector, end, start);
return;
}

length = end->value.integer - start->value.integer;

assert(length >= 0);
if (length < 0) {
throw(vm, "A slice cannot have netative length.",
3, vector, end, start);
return;
}

/* Vector and bytevector have the same internal structure, the only
difference are the final pointer types. We can use this to avoid
extraneous allocations and make accessing the members easier. */
vm->reg2 = vm_alloc(vm, SLICE);
vm->reg2->type = vector->type;

vm->reg2->value.byte_vector.length = MIN(length, vector->value.byte_vector.length);
vm->reg2->value.byte_vector.length = MIN(
length, vector->value.byte_vector.length);

vm->reg2->value.byte_vector.slice = true;

/* We need to know the type to determine the size to offset by. */
Expand All @@ -177,7 +214,10 @@ void op_string_slice(vm_internal_type *vm) {

vm->reg1 = string = vm_pop(vm);

assert(string && string->type == STRING);
if (string->type != STRING) {
throw(vm, "String slice requires a string argument.", 1, string);
return;
}

vm->reg2 = slice = vm_alloc(vm, SLICE);
slice->type = BYTE_VECTOR;
Expand Down
Loading

0 comments on commit ca4feef

Please sign in to comment.