Rework KrkValue to use NaN-boxing

This commit is contained in:
K Lange 2021-03-24 20:23:15 +09:00
parent 073a5828d0
commit 2ed8e65c89
12 changed files with 156 additions and 154 deletions

View File

@ -7,7 +7,7 @@ def processFile(sourcePath, pid, cmd):
with fileio.open(sourcePath,'r') as f:
for line in f.readlines():
let callerFile, callerFunc, callerLine, calleeFile, calleeFunc, calleeLine, nsecs = line.split(' ')
nsecs = int(nsecs)
nsecs = int(nsecs[:-2])
let data = funcs.get((callerFile,callerFunc),{})
let call = data.get((callerLine,calleeFile,calleeFunc,calleeLine),(0,0))
let out = (call[0] + 1, call[1] + nsecs)
@ -37,7 +37,7 @@ def processFile(sourcePath, pid, cmd):
let count, nsecs = v
totalNsecs -= nsecs
out.write(f'{startLine} {totalNsecs}\n')
out.write(f'{startLine} {totalNsecs}00\n')
for k, v in value.items():
if not k: continue
let sourceLine, file, func, destLine = k
@ -45,5 +45,5 @@ def processFile(sourcePath, pid, cmd):
if file != sFile: out.write(f'cfi={file}\n')
out.write(f'cfn={func}\n')
out.write(f'calls={count} {destLine}\n')
out.write(f'{sourceLine} {totalNsecs}\n')
out.write(f'{sourceLine} {totalNsecs}00\n')
out.write('\n')

View File

@ -8,20 +8,20 @@
#include <stdlib.h>
#if defined(__EMSCRIPTEN__)
typedef long long krk_integer_type;
# define PRIkrk_int "%lld"
# define PRIkrk_hex "%llx"
# define parseStrInt strtoll
typedef int krk_integer_type;
# define PRIkrk_int "%d"
# define PRIkrk_hex "%x"
# define parseStrInt strtol
#elif defined(_WIN32)
typedef long long krk_integer_type;
# define PRIkrk_int "%I64d"
# define PRIkrk_hex "%I64x"
# define parseStrInt strtoll
typedef int krk_integer_type;
# define PRIkrk_int "%I32d"
# define PRIkrk_hex "%I32x"
# define parseStrInt strtol
# define ENABLE_THREADING
# else
typedef long krk_integer_type;
# define PRIkrk_int "%ld"
# define PRIkrk_hex "%lx"
typedef int krk_integer_type;
# define PRIkrk_int "%d"
# define PRIkrk_hex "%x"
# define parseStrInt strtol
# define ENABLE_THREADING
#endif

View File

@ -4,6 +4,7 @@
* @brief Definitions for primitive stack references.
*/
#include <stdio.h>
#include <string.h>
#include "kuroko.h"
/**
@ -18,37 +19,26 @@ typedef struct KrkString KrkString;
/**
* @brief Tag enum for basic value types.
*
* Value types are tagged unions of a handful of small
* types represented directly on the stack: Integers,
* double-precision floating point values, booleans,
* exception handler references, complex function argument
* processing sentinels, object reference pointers, and None.
* These are the values stored in the upper NaN bits of
* the boxed NaN values.
*/
typedef enum {
KRK_VAL_NONE,
KRK_VAL_BOOLEAN,
KRK_VAL_INTEGER,
KRK_VAL_FLOATING,
KRK_VAL_HANDLER,
KRK_VAL_OBJECT,
KRK_VAL_KWARGS,
KRK_VAL_BOOLEAN = 0xFFFC,
KRK_VAL_INTEGER = 0xFFFD,
KRK_VAL_HANDLER = 0xFFFE,
KRK_VAL_NONE = 0xFFFF,
KRK_VAL_KWARGS = 0x7FFC,
KRK_VAL_OBJECT = 0x7FFD,
} KrkValueType;
/**
* @brief Stack value representation of a 'with' or 'try' block.
*
* When a 'with' or 'try' block is entered, a handler value is
* created on the stack representing the type (with, try) and the
* jump target to leave the block (entering the 'except' block of
* a 'try', if present, or calling the __exit__ method of an object
* __enter__'d by a 'with' block). When the relevant conditions are
* triggered in the VM, the stack will be scanned from top to bottom
* to look for these values.
*/
typedef struct {
unsigned short type;
unsigned short target;
} KrkJumpTarget;
#define KRK_VAL_MASK_BOOLEAN ((uint64_t)0xFFFC000000000000) /* 1..1100 */
#define KRK_VAL_MASK_INTEGER ((uint64_t)0xFFFD000000000000) /* 1..1101 */
#define KRK_VAL_MASK_HANDLER ((uint64_t)0xFFFE000000000000) /* 1..1110 */
#define KRK_VAL_MASK_NONE ((uint64_t)0xFFFF000000000000) /* 1..1111 */
#define KRK_VAL_MASK_KWARGS ((uint64_t)0x7FFC000000000000) /* 0..1100 */
#define KRK_VAL_MASK_OBJECT ((uint64_t)0x7FFD000000000000) /* 0..1101 */
#define KRK_VAL_MASK_NAN ((uint64_t)0x7FFC000000000000)
#define KRK_VAL_MASK_LOW ((uint64_t)0x0000FFFFFFFFFFFF)
/**
* @brief Stack reference or primative value.
@ -59,19 +49,11 @@ typedef struct {
* direct copying rather than as pointers, avoiding the need to track
* memory used by them.
*
* Each value is a tagged union with a type (see the enum KrkValueType)
* and its contents.
* Implemented through basic NaN-boxing where the top sixteen bits are
* used as a tag (@ref KrkValueType) and the lower 32 or 48 bits contain
* the various primitive types.
*/
typedef struct {
KrkValueType type;
union {
char boolean;
krk_integer_type integer;
double floating;
KrkJumpTarget handler;
KrkObj * object;
} as;
} KrkValue;
typedef uint64_t KrkValue;
/**
* @brief Flexible vector of stack references.
@ -183,30 +165,51 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b);
*/
extern int krk_valuesSame(KrkValue a, KrkValue b);
#define BOOLEAN_VAL(value) ((KrkValue){KRK_VAL_BOOLEAN, {.integer = value}})
#define NONE_VAL(value) ((KrkValue){KRK_VAL_NONE, {.integer = 0}})
#define INTEGER_VAL(value) ((KrkValue){KRK_VAL_INTEGER, {.integer = value}})
#define FLOATING_VAL(value) ((KrkValue){KRK_VAL_FLOATING,{.floating = value}})
#define HANDLER_VAL(ty,ta) ((KrkValue){KRK_VAL_HANDLER, {.handler = (KrkJumpTarget){.type = ty, .target = ta}}})
#define OBJECT_VAL(value) ((KrkValue){KRK_VAL_OBJECT, {.object = (KrkObj*)value}})
#define KWARGS_VAL(value) ((KrkValue){KRK_VAL_KWARGS, {.integer = value}})
#define NONE_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NONE))
#define BOOLEAN_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_BOOLEAN))
#define INTEGER_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_INTEGER))
#define KWARGS_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_KWARGS))
#define OBJECT_VAL(value) ((KrkValue)(((uintptr_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_OBJECT))
#define HANDLER_VAL(ty,ta) ((KrkValue)((uint32_t)((((uint16_t)ty) << 16) | ((uint16_t)ta)) | KRK_VAL_MASK_HANDLER))
#define FLOATING_VAL(value) (krk_dbl_as_val(value))
#define AS_BOOLEAN(value) ((value).as.integer)
#define AS_INTEGER(value) ((value).as.integer)
#define AS_FLOATING(value) ((value).as.floating)
#define AS_HANDLER(value) ((value).as.handler)
#define AS_OBJECT(value) ((value).as.object)
#define KRK_VAL_TYPE(value) ((value) >> 48)
#define IS_BOOLEAN(value) ((value).type == KRK_VAL_BOOLEAN)
#define IS_NONE(value) ((value).type == KRK_VAL_NONE)
#define IS_INTEGER(value) (((value).type == KRK_VAL_INTEGER) || ((value.type) == KRK_VAL_BOOLEAN))
#define IS_FLOATING(value) ((value).type == KRK_VAL_FLOATING)
#define IS_HANDLER(value) ((value).type == KRK_VAL_HANDLER)
#define IS_OBJECT(value) ((value).type == KRK_VAL_OBJECT)
#define IS_KWARGS(value) ((value).type == KRK_VAL_KWARGS)
#define AS_BOOLEAN(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW))
#define AS_INTEGER(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW))
#define AS_HANDLER(value) ((uint32_t)((value) & KRK_VAL_MASK_LOW))
#define AS_OBJECT(value) ((KrkObj*)(uintptr_t)((value) & KRK_VAL_MASK_LOW))
#define AS_FLOATING(value) (krk_val_as_dbl(value))
#define IS_TRY_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_TRY)
#define IS_WITH_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_WITH)
#define IS_RAISE_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_RAISE)
#define IS_EXCEPT_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_FILTER_EXCEPT)
static inline double krk_val_as_dbl(KrkValue val) {
double out;
memcpy(&out,&val,sizeof(KrkValue));
return out;
}
static inline KrkValue krk_dbl_as_val(double dbl) {
KrkValue out;
memcpy(&out,&dbl,sizeof(KrkValue));
return out;
}
#define IS_INTEGER(value) (((value) & KRK_VAL_MASK_HANDLER) == KRK_VAL_MASK_BOOLEAN)
#define IS_BOOLEAN(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_BOOLEAN)
#define IS_NONE(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_NONE)
#define IS_HANDLER(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_HANDLER)
#define IS_OBJECT(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_OBJECT)
#define IS_KWARGS(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_KWARGS)
#define IS_FLOATING(value) (((value) & KRK_VAL_MASK_NAN) != KRK_VAL_MASK_NAN)
#define AS_HANDLER_TYPE(value) (AS_HANDLER(value) >> 16)
#define AS_HANDLER_TARGET(value) (AS_HANDLER(value) & 0xFFFF)
#define IS_TRY_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_PUSH_TRY)
#define IS_WITH_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_PUSH_WITH)
#define IS_RAISE_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_RAISE)
#define IS_EXCEPT_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_FILTER_EXCEPT)
#define KWARGS_SINGLE (INT32_MAX)
#define KWARGS_LIST (INT32_MAX-1)
#define KWARGS_DICT (INT32_MAX-2)
#define KWARGS_NIL (INT32_MAX-3)
#define KWARGS_UNSET (0)

View File

@ -18,7 +18,7 @@
}
#define FORCE_FLOAT(arg) \
if (!IS_FLOATING(arg)) { switch (arg.type) { \
if (!IS_FLOATING(arg)) { switch (KRK_VAL_TYPE(arg)) { \
case KRK_VAL_INTEGER: arg = FLOATING_VAL(AS_INTEGER(arg)); break; \
case KRK_VAL_BOOLEAN: arg = FLOATING_VAL(AS_BOOLEAN(arg)); break; \
default: { \

View File

@ -16,7 +16,7 @@ static KrkValue _tuple_init(int argc, KrkValue argv[], int hasKw) {
/* Convert this to a call to tupleOf(*arg) */
KrkValue tupleOf;
krk_tableGet(&vm.builtins->fields, OBJECT_VAL(S("tupleOf")), &tupleOf);
krk_push(KWARGS_VAL(LONG_MAX-1));
krk_push(KWARGS_VAL(KWARGS_LIST));
krk_push(argv[1]);
krk_push(KWARGS_VAL(1));
krk_push(krk_callSimple(tupleOf, 3, 0));

View File

@ -22,13 +22,14 @@ void krk_freeTable(KrkTable * table) {
}
inline uint32_t krk_hashValue(KrkValue value) {
switch (value.type) {
switch (KRK_VAL_TYPE(value)) {
case KRK_VAL_INTEGER: return (uint32_t)(AS_INTEGER(value));
case KRK_VAL_FLOATING: return (uint32_t)(AS_FLOATING(value) * 1000); /* arbitrary; what's a good way to hash floats? */
case KRK_VAL_BOOLEAN: return (uint32_t)(AS_BOOLEAN(value));
case KRK_VAL_NONE: return 0;
case KRK_VAL_OBJECT: return (uint32_t)(AS_OBJECT(value))->hash;
default: return 0;
default:
if (IS_FLOATING(value)) return (uint32_t)(AS_FLOATING(value) * 1000); /* arbitrary; what's a good way to hash floats? */
return 0;
}
}

View File

@ -48,38 +48,39 @@ void krk_printValue(FILE * f, KrkValue printable) {
void krk_printValueSafe(FILE * f, KrkValue printable) {
if (!IS_OBJECT(printable)) {
switch (printable.type) {
switch (KRK_VAL_TYPE(printable)) {
case KRK_VAL_INTEGER: fprintf(f, PRIkrk_int, AS_INTEGER(printable)); break;
case KRK_VAL_BOOLEAN: fprintf(f, "%s", AS_BOOLEAN(printable) ? "True" : "False"); break;
case KRK_VAL_FLOATING: fprintf(f, "%.16g", AS_FLOATING(printable)); break;
case KRK_VAL_NONE: fprintf(f, "None"); break;
case KRK_VAL_HANDLER:
switch (AS_HANDLER(printable).type) {
case OP_PUSH_TRY: fprintf(f, "{try->%d}", (int)AS_HANDLER(printable).target); break;
case OP_PUSH_WITH: fprintf(f, "{with->%d}", (int)AS_HANDLER(printable).target); break;
case OP_RAISE: fprintf(f, "{raise<-%d}", (int)AS_HANDLER(printable).target); break;
case OP_FILTER_EXCEPT: fprintf(f, "{except<-%d}", (int)AS_HANDLER(printable).target); break;
case OP_BEGIN_FINALLY: fprintf(f, "{finally<-%d}", (int)AS_HANDLER(printable).target); break;
case OP_RETURN: fprintf(f, "{return<-%d}", (int)AS_HANDLER(printable).target); break;
switch (AS_HANDLER_TYPE(printable)) {
case OP_PUSH_TRY: fprintf(f, "{try->%d}", (int)AS_HANDLER_TARGET(printable)); break;
case OP_PUSH_WITH: fprintf(f, "{with->%d}", (int)AS_HANDLER_TARGET(printable)); break;
case OP_RAISE: fprintf(f, "{raise<-%d}", (int)AS_HANDLER_TARGET(printable)); break;
case OP_FILTER_EXCEPT: fprintf(f, "{except<-%d}", (int)AS_HANDLER_TARGET(printable)); break;
case OP_BEGIN_FINALLY: fprintf(f, "{finally<-%d}", (int)AS_HANDLER_TARGET(printable)); break;
case OP_RETURN: fprintf(f, "{return<-%d}", (int)AS_HANDLER_TARGET(printable)); break;
}
break;
case KRK_VAL_KWARGS: {
if (AS_INTEGER(printable) == LONG_MAX) {
if (AS_INTEGER(printable) == KWARGS_SINGLE) {
fprintf(f, "{unpack single}");
} else if (AS_INTEGER(printable) == LONG_MAX-1) {
} else if (AS_INTEGER(printable) == KWARGS_LIST) {
fprintf(f, "{unpack list}");
} else if (AS_INTEGER(printable) == LONG_MAX-2) {
} else if (AS_INTEGER(printable) == KWARGS_DICT) {
fprintf(f, "{unpack dict}");
} else if (AS_INTEGER(printable) == LONG_MAX-3) {
} else if (AS_INTEGER(printable) == KWARGS_NIL) {
fprintf(f, "{unpack nil}");
} else if (AS_INTEGER(printable) == 0) {
} else if (AS_INTEGER(printable) == KWARGS_UNSET) {
fprintf(f, "{unset default}");
} else {
fprintf(f, "{sentinel=" PRIkrk_int "}",AS_INTEGER(printable));
}
break;
}
default: break;
default:
if (IS_FLOATING(printable)) fprintf(f, "%.16g", AS_FLOATING(printable));
break;
}
} else if (IS_STRING(printable)) {
fprintf(f, "'");
@ -137,7 +138,7 @@ void krk_printValueSafe(FILE * f, KrkValue printable) {
}
int krk_valuesSame(KrkValue a, KrkValue b) {
if (a.type != b.type) return 0;
if (KRK_VAL_TYPE(a) != KRK_VAL_TYPE(b)) return 0;
if (IS_OBJECT(a)) return AS_OBJECT(a) == AS_OBJECT(b);
return krk_valuesEqual(a,b);
}
@ -145,13 +146,12 @@ int krk_valuesSame(KrkValue a, KrkValue b) {
__attribute__((hot))
inline
int krk_valuesEqual(KrkValue a, KrkValue b) {
if (a.type == b.type) {
switch (a.type) {
if (KRK_VAL_TYPE(a) == KRK_VAL_TYPE(b)) {
switch (KRK_VAL_TYPE(a)) {
case KRK_VAL_BOOLEAN: return AS_BOOLEAN(a) == AS_BOOLEAN(b);
case KRK_VAL_NONE: return 1; /* None always equals None */
case KRK_VAL_KWARGS: /* Equal if same number of args; may be useful for comparing sentinels (0) to arg lists. */
case KRK_VAL_INTEGER: return AS_INTEGER(a) == AS_INTEGER(b);
case KRK_VAL_FLOATING: return AS_FLOATING(a) == AS_FLOATING(b);
case KRK_VAL_HANDLER: krk_runtimeError(vm.exceptions->valueError,"Invalid value"); return 0;
case KRK_VAL_OBJECT: {
if (AS_OBJECT(a) == AS_OBJECT(b)) return 1;
@ -159,33 +159,29 @@ int krk_valuesEqual(KrkValue a, KrkValue b) {
default: break;
}
}
if (IS_FLOATING(a) && IS_FLOATING(b)) return AS_FLOATING(a) == AS_FLOATING(b);
if (IS_KWARGS(a) || IS_KWARGS(b)) return 0;
if (!IS_OBJECT(a) && !IS_OBJECT(b)) {
switch (a.type) {
switch (KRK_VAL_TYPE(a)) {
case KRK_VAL_INTEGER: {
switch (b.type) {
case KRK_VAL_BOOLEAN: return AS_INTEGER(a) == AS_BOOLEAN(b);
case KRK_VAL_FLOATING: return (double)AS_INTEGER(a) == AS_FLOATING(b);
default: return 0;
}
} break;
case KRK_VAL_FLOATING: {
switch (b.type) {
case KRK_VAL_BOOLEAN: return AS_FLOATING(a) == (double)AS_BOOLEAN(b);
case KRK_VAL_INTEGER: return AS_FLOATING(a) == (double)AS_INTEGER(b);
default: return 0;
}
if (IS_BOOLEAN(b)) return AS_INTEGER(a) == AS_BOOLEAN(b);
else if (IS_FLOATING(b)) return (double)AS_INTEGER(a) == AS_FLOATING(b);
return 0;
} break;
case KRK_VAL_BOOLEAN: {
switch (b.type) {
case KRK_VAL_INTEGER: return AS_BOOLEAN(a) == AS_INTEGER(b);
case KRK_VAL_FLOATING: return (double)AS_BOOLEAN(a) == AS_FLOATING(b);
default: return 0;
}
if (IS_INTEGER(b)) return AS_INTEGER(a) == AS_BOOLEAN(b);
else if (IS_FLOATING(b)) return (double)AS_INTEGER(a) == AS_FLOATING(b);
return 0;
} break;
default: return 0;
default:
if (IS_FLOATING(a)) {
if (IS_BOOLEAN(b)) return AS_FLOATING(a) == (double)AS_BOOLEAN(b);
else if (IS_INTEGER(b)) return AS_FLOATING(a) == (double)AS_INTEGER(b);
return 0;
}
break;
}
}

View File

@ -448,11 +448,9 @@ void krk_finalizeClass(KrkClass * _class) {
* Internal version of type().
*/
inline KrkClass * krk_getType(KrkValue of) {
switch (of.type) {
switch (KRK_VAL_TYPE(of)) {
case KRK_VAL_INTEGER:
return vm.baseClasses->intClass;
case KRK_VAL_FLOATING:
return vm.baseClasses->floatClass;
case KRK_VAL_BOOLEAN:
return vm.baseClasses->boolClass;
case KRK_VAL_NONE:
@ -480,6 +478,7 @@ inline KrkClass * krk_getType(KrkValue of) {
return vm.baseClasses->objectClass;
} break;
default:
if (IS_FLOATING(of)) return vm.baseClasses->floatClass;
return vm.baseClasses->objectClass;
}
}
@ -557,9 +556,9 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa
KrkValue key = startOfExtras[i*2];
KrkValue value = startOfExtras[i*2 + 1];
if (IS_KWARGS(key)) {
if (AS_INTEGER(key) == LONG_MAX-1) { /* unpack list */
if (AS_INTEGER(key) == KWARGS_LIST) { /* unpack list */
unpackIterableFast(value);
} else if (AS_INTEGER(key) == LONG_MAX-2) { /* unpack dict */
} else if (AS_INTEGER(key) == KWARGS_DICT) { /* unpack dict */
if (!IS_INSTANCE(value)) {
krk_runtimeError(vm.exceptions->typeError, "**expression value is not a dict.");
return 0;
@ -577,7 +576,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa
}
}
}
} else if (AS_INTEGER(key) == LONG_MAX) { /* single value */
} else if (AS_INTEGER(key) == KWARGS_SINGLE) { /* single value */
krk_writeValueArray(positionals, value);
}
} else if (IS_STRING(key)) {
@ -1002,19 +1001,21 @@ void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) {
* going to take the else branch.
*/
int krk_isFalsey(KrkValue value) {
switch (value.type) {
switch (KRK_VAL_TYPE(value)) {
case KRK_VAL_NONE: return 1;
case KRK_VAL_BOOLEAN: return !AS_BOOLEAN(value);
case KRK_VAL_INTEGER: return !AS_INTEGER(value);
case KRK_VAL_FLOATING: return !AS_FLOATING(value);
case KRK_VAL_OBJECT: {
switch (AS_OBJECT(value)->type) {
case KRK_OBJ_STRING: return !AS_STRING(value)->codesLength;
case KRK_OBJ_TUPLE: return !AS_TUPLE(value)->values.count;
default: break;
}
break;
}
default: break;
default:
if (IS_FLOATING(value)) return !AS_FLOATING(value);
break;
}
KrkClass * type = krk_getType(value);
@ -2016,7 +2017,7 @@ _resumeHook: (void)0;
KrkValue contextManager = krk_peek(2);
KrkClass * type = krk_getType(contextManager);
krk_push(contextManager);
if (AS_HANDLER(handler).type == OP_RAISE) {
if (AS_HANDLER_TYPE(handler) == OP_RAISE) {
krk_push(OBJECT_VAL(krk_getType(exceptionObject)));
krk_push(exceptionObject);
KrkValue tracebackEntries = NONE_VAL();
@ -2038,7 +2039,7 @@ _resumeHook: (void)0;
krk_callSimple(OBJECT_VAL(type->_exit), 4, 0);
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) goto _finishException;
}
if (AS_HANDLER(handler).type != OP_RETURN) break;
if (AS_HANDLER_TYPE(handler) != OP_RETURN) break;
krk_pop(); /* handler */
} /* fallthrough */
case OP_RETURN: {
@ -2055,8 +2056,8 @@ _finishReturn: (void)0;
; stackOffset--);
if (stackOffset >= (int)frame->slots) {
krk_currentThread.stackTop = &krk_currentThread.stack[stackOffset + 1];
frame->ip = frame->closure->function->chunk.code + AS_HANDLER(krk_peek(0)).target;
AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_RETURN;
frame->ip = frame->closure->function->chunk.code + AS_HANDLER_TARGET(krk_peek(0));
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_RETURN,AS_HANDLER_TARGET(krk_peek(0)));
krk_currentThread.stackTop[-2] = result;
break;
}
@ -2248,9 +2249,9 @@ _finishReturn: (void)0;
break;
case OP_FILTER_EXCEPT: {
int isMatch = 0;
if (AS_HANDLER(krk_peek(1)).type == OP_RETURN) {
if (AS_HANDLER_TYPE(krk_peek(1)) == OP_RETURN) {
isMatch = 0;
} else if (AS_HANDLER(krk_peek(1)).type == OP_END_FINALLY) {
} else if (AS_HANDLER_TYPE(krk_peek(1)) == OP_END_FINALLY) {
isMatch = 0;
} else if (IS_CLASS(krk_peek(0)) && krk_isInstanceOf(krk_peek(2), AS_CLASS(krk_peek(0)))) {
isMatch = 1;
@ -2265,7 +2266,7 @@ _finishReturn: (void)0;
isMatch = !IS_NONE(krk_peek(2));
}
if (isMatch) {
AS_HANDLER(krk_currentThread.stackTop[-2]).type = OP_FILTER_EXCEPT;
krk_currentThread.stackTop[-2] = HANDLER_VAL(OP_FILTER_EXCEPT,AS_HANDLER_TARGET(krk_peek(1)));
}
krk_pop();
krk_push(BOOLEAN_VAL(isMatch));
@ -2273,10 +2274,10 @@ _finishReturn: (void)0;
}
case OP_BEGIN_FINALLY: {
if (IS_HANDLER(krk_peek(0))) {
if (AS_HANDLER(krk_peek(0)).type == OP_PUSH_TRY) {
AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_BEGIN_FINALLY;
} else if (AS_HANDLER(krk_peek(0)).type == OP_FILTER_EXCEPT) {
AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_BEGIN_FINALLY;
if (AS_HANDLER_TYPE(krk_peek(0)) == OP_PUSH_TRY) {
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_BEGIN_FINALLY,AS_HANDLER_TARGET(krk_peek(0)));
} else if (AS_HANDLER_TYPE(krk_peek(0)) == OP_FILTER_EXCEPT) {
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_BEGIN_FINALLY,AS_HANDLER_TARGET(krk_peek(0)));
}
}
break;
@ -2284,12 +2285,12 @@ _finishReturn: (void)0;
case OP_END_FINALLY: {
KrkValue handler = krk_peek(0);
if (IS_HANDLER(handler)) {
if (AS_HANDLER(handler).type == OP_RAISE || AS_HANDLER(handler).type == OP_END_FINALLY) {
if (AS_HANDLER_TYPE(handler) == OP_RAISE || AS_HANDLER_TYPE(handler) == OP_END_FINALLY) {
krk_pop(); /* handler */
krk_currentThread.currentException = krk_pop();
krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION;
goto _finishException;
} else if (AS_HANDLER(handler).type == OP_RETURN) {
} else if (AS_HANDLER_TYPE(handler) == OP_RETURN) {
krk_push(krk_peek(1));
goto _finishReturn;
}
@ -2486,7 +2487,7 @@ _finishReturn: (void)0;
case OP_EXPAND_ARGS_LONG:
case OP_EXPAND_ARGS: {
int type = OPERAND;
krk_push(KWARGS_VAL(LONG_MAX-type));
krk_push(KWARGS_VAL(KWARGS_SINGLE-type));
break;
}
case OP_CLOSURE_LONG:
@ -2747,12 +2748,12 @@ _finishReturn: (void)0;
_finishException:
if (!handleException()) {
frame = &krk_currentThread.frames[krk_currentThread.frameCount - 1];
frame->ip = frame->closure->function->chunk.code + AS_HANDLER(krk_peek(0)).target;
frame->ip = frame->closure->function->chunk.code + AS_HANDLER_TARGET(krk_peek(0));
/* Stick the exception into the exception slot */
if (AS_HANDLER(krk_currentThread.stackTop[-1]).type == OP_FILTER_EXCEPT) {
AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_END_FINALLY;
if (AS_HANDLER_TYPE(krk_currentThread.stackTop[-1])== OP_FILTER_EXCEPT) {
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_END_FINALLY,AS_HANDLER_TARGET(krk_peek(0)));
} else {
AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_RAISE;
krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_RAISE,AS_HANDLER_TARGET(krk_peek(0)));
}
krk_currentThread.stackTop[-2] = krk_currentThread.currentException;
krk_currentThread.currentException = NONE_VAL();

View File

@ -33,6 +33,6 @@ def __main__():
ordering[m3] = px
m0 = ordering[m0]
print(ordering[1]*ordering[ordering[1]])
print(str(float(ordering[1])*ordering[ordering[1]]).replace('.0',''))
__main__()

View File

@ -41,5 +41,5 @@ class Baz(object):
let b = Baz()
print(b.bar)
b.bar = 0xDEADBEEF
b.bar = 0xCAFE
print(b.bar)

View File

@ -8,6 +8,6 @@ Called as a setter: [102]
<class '__main__.Bar'> test
I am a Python-style @property!
42
I am a Python-style @property's setter called with 3735928559
I am a Python-style @property's setter called with 51966
I am a Python-style @property!
3735928559
51966

View File

@ -303,7 +303,7 @@ static int doSecondPass(FILE * out) {
for (size_t i = 0; i < func->chunk.constants.count; ++i) {
KrkValue * val = &func->chunk.constants.values[i];
switch (val->type) {
switch (KRK_VAL_TYPE(*val)) {
case KRK_VAL_OBJECT:
switch (AS_OBJECT(*val)->type) {
case KRK_OBJ_STRING:
@ -329,10 +329,11 @@ static int doSecondPass(FILE * out) {
case KRK_VAL_INTEGER:
WRITE_INTEGER(AS_INTEGER(*val));
break;
case KRK_VAL_FLOATING:
default:
if (IS_FLOATING(*val)) {
WRITE_FLOATING(AS_FLOATING(*val));
break;
default:
}
fprintf(stderr,
"Invalid value found in constants table,"
"this marashal format can not store '%s'\n",