diff --git a/src/core/compiler.c b/src/core/compiler.c index 55ab6e1..4420655 100644 --- a/src/core/compiler.c +++ b/src/core/compiler.c @@ -769,7 +769,12 @@ static void eatString(Compiler* compiler, bool single_quote) { } break; + case '\r': + if (matchChar(parser, '\n')) break; + // Else fallthrough. + default: + semanticError(compiler, makeErrToken(parser), "Invalid escape character."); break; diff --git a/src/core/core.c b/src/core/core.c index a036c7d..bf7896b 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -1629,7 +1629,7 @@ bool varContains(PKVM* vm, Var elem, Var container) { bool varIsType(PKVM* vm, Var inst, Var type) { if (!IS_OBJ_TYPE(type, OBJ_CLASS)) { VM_SET_ERROR(vm, newString(vm, "Right operand must be a class.")); - return VAR_NULL; + return false; } Class* cls = (Class*)AS_OBJ(type); diff --git a/src/core/public.c b/src/core/public.c index c7938fb..a55caf5 100644 --- a/src/core/public.c +++ b/src/core/public.c @@ -860,6 +860,7 @@ bool pkNewInstance(PKVM* vm, int cls, int index, int argc, int argv) { bool pkCallFunction(PKVM* vm, int fn, int argc, int argv, int ret) { CHECK_FIBER_EXISTS(vm); + ASSERT(IS_OBJ_TYPE(SLOT(fn), OBJ_CLOSURE), "Slot value wasn't a function"); if (argc != 0) { VALIDATE_SLOT_INDEX(argv); VALIDATE_SLOT_INDEX(argv + argc - 1); @@ -868,7 +869,7 @@ bool pkCallFunction(PKVM* vm, int fn, int argc, int argv, int ret) { // Calls a class == construct. if (IS_OBJ_TYPE(SLOT(fn), OBJ_CLASS)) { - Var inst = _newInstance(vm, (Class*) AS_OBJ(fn), argc, + Var inst = _newInstance(vm, (Class*) AS_OBJ(SLOT(fn)), argc, vm->fiber->ret + argv); if (ret >= 0) SET_SLOT(ret, inst); return !VM_HAS_ERROR(vm); diff --git a/src/core/vm.c b/src/core/vm.c index 8861f51..b22255c 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -321,8 +321,11 @@ PkResult vmCallMethod(PKVM* vm, Var self, Closure* fn, fiber->self = self; vmPushTempRef(vm, &fiber->_super); // fiber. bool success = vmPrepareFiber(vm, fiber, argc, argv); - vmPopTempRef(vm); // fiber. - if (!success) return PK_RESULT_RUNTIME_ERROR; + + if (!success) { + vmPopTempRef(vm); // fiber. + return PK_RESULT_RUNTIME_ERROR; + } PkResult result; @@ -345,7 +348,10 @@ PkResult vmCallMethod(PKVM* vm, Var self, Closure* fn, result = vmRunFiber(vm, fiber); } } + if (last != NULL) vmPopTempRef(vm); // last. + vmPopTempRef(vm); // fiber. + vm->fiber = last; if (ret != NULL) *ret = *fiber->ret; @@ -515,7 +521,11 @@ static inline void pushCallFrame(PKVM* vm, const Closure* closure) { // Grow the stack frame if needed. if (vm->fiber->frame_count + 1 > vm->fiber->frame_capacity) { + + // Native functions doesn't allocate a frame initially. int new_capacity = vm->fiber->frame_capacity << 1; + if (new_capacity == 0) new_capacity = 1; + vm->fiber->frames = (CallFrame*)vmRealloc(vm, vm->fiber->frames, sizeof(CallFrame) * vm->fiber->frame_capacity, sizeof(CallFrame) * new_capacity); @@ -691,11 +701,11 @@ PkResult vmRunFiber(PKVM* vm, Fiber* fiber_) { register Fiber* fiber = fiber_; #if DEBUG - #define PUSH(value) \ - do { \ - ASSERT(fiber->sp < (fiber->stack + (fiber->stack_size - 1)), \ - OOPS); \ - (*fiber->sp++ = (value)); \ + #define PUSH(value) \ + do { \ + ASSERT(fiber->sp < (fiber->stack + ((intptr_t) fiber->stack_size - 1)), \ + OOPS); \ + (*fiber->sp++ = (value)); \ } while (false) #else #define PUSH(value) (*fiber->sp++ = (value))