Add support for building without nan-boxing
This commit is contained in:
parent
df4435efdc
commit
b162ed889b
4
Makefile
4
Makefile
@ -84,6 +84,10 @@ ifdef KRK_HEAP_TAG_BYTE
|
||||
CFLAGS += -DKRK_HEAP_TAG_BYTE=${KRK_HEAP_TAG_BYTE}
|
||||
endif
|
||||
|
||||
ifdef KRK_NO_NAN_BOXING
|
||||
CFLAGS += -DKRK_NO_NAN_BOXING=1
|
||||
endif
|
||||
|
||||
ifdef KRK_BUNDLE_LIBS
|
||||
KRK_BUNDLE_LIBS_CFLAG=$(patsubst %,BUNDLED(%);,${KRK_BUNDLE_LIBS})
|
||||
KRK_BUNDLE_LIBS_BOBJS=$(patsubst %,src/modules/module_%.o,${KRK_BUNDLE_LIBS})
|
||||
|
@ -476,7 +476,7 @@ KrkValue krk_runtimeError(KrkClass * type, const char * fmt, ...) {
|
||||
/* Allocate an exception object of the requested type. */
|
||||
KrkInstance * exceptionObject = krk_newInstance(type);
|
||||
krk_push(OBJECT_VAL(exceptionObject));
|
||||
krk_attachNamedValue(&exceptionObject->fields, "arg", msg == KWARGS_VAL(0) ? finishStringBuilder(&sb) : msg);
|
||||
krk_attachNamedValue(&exceptionObject->fields, "arg", krk_valuesSame(msg,KWARGS_VAL(0)) ? finishStringBuilder(&sb) : msg);
|
||||
krk_attachNamedValue(&exceptionObject->fields, "__cause__", NONE_VAL());
|
||||
krk_attachNamedValue(&exceptionObject->fields, "__context__", NONE_VAL());
|
||||
krk_pop();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include "kuroko.h"
|
||||
|
||||
#ifndef KRK_NO_NAN_BOXING
|
||||
/**
|
||||
* @brief Tag enum for basic value types.
|
||||
*
|
||||
@ -23,28 +24,6 @@ typedef enum {
|
||||
KRK_VAL_NOTIMPL = 0x7FFE,
|
||||
} KrkValueType;
|
||||
|
||||
/*
|
||||
* The following poorly-named macros define bit patterns for identifying
|
||||
* various boxed types.
|
||||
*
|
||||
* Boxing is done by first setting all of the bits of MASK_NAN. If all of
|
||||
* these bits are set, a value is not a float. If any of them are not set,
|
||||
* then a value is a float - and possibly a real NaN.
|
||||
*
|
||||
* Three other bits - one before and two after the MASK_NAN bits - determine
|
||||
* what type the value actually is. KWARGS sets none of the identifying bits,
|
||||
* NONE sets all of them.
|
||||
*/
|
||||
#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_NOTIMPL ((uint64_t)0x7FFE000000000000) /* 0..1110 */
|
||||
#define KRK_VAL_MASK_NAN ((uint64_t)0x7FFC000000000000)
|
||||
#define KRK_VAL_MASK_LOW ((uint64_t)0x0000FFFFFFFFFFFF)
|
||||
|
||||
/**
|
||||
* @struct KrkValue
|
||||
* @brief Stack reference or primative value.
|
||||
@ -61,6 +40,32 @@ typedef enum {
|
||||
*/
|
||||
typedef uint64_t KrkValue;
|
||||
|
||||
#define _krk_valuesSame(a,b) (a == b)
|
||||
|
||||
#else
|
||||
/*
|
||||
* Tagged union, but without the union fun.
|
||||
*/
|
||||
typedef enum {
|
||||
KRK_VAL_NONE = 0,
|
||||
KRK_VAL_INTEGER = 1,
|
||||
KRK_VAL_BOOLEAN = 2,
|
||||
KRK_VAL_HANDLER = 4,
|
||||
KRK_VAL_KWARGS = 8,
|
||||
KRK_VAL_OBJECT = 16,
|
||||
KRK_VAL_NOTIMPL = 32,
|
||||
KRK_VAL_FLOATING = 64,
|
||||
} KrkValueType;
|
||||
|
||||
typedef struct {
|
||||
uint64_t tag;
|
||||
uint64_t val;
|
||||
} KrkValue;
|
||||
|
||||
#define _krk_valuesSame(a,b) (memcmp(&(a),&(b),sizeof(KrkValue)) == 0)
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Flexible vector of stack references.
|
||||
*
|
||||
@ -133,7 +138,7 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b);
|
||||
*
|
||||
* @return 1 if values represent the same object or value, 0 otherwise.
|
||||
*/
|
||||
extern int krk_valuesSame(KrkValue a, KrkValue b);
|
||||
static inline int krk_valuesSame(KrkValue a, KrkValue b) { return _krk_valuesSame(a,b); }
|
||||
|
||||
/**
|
||||
* @brief Compare two values by identity, then by equality.
|
||||
@ -147,11 +152,35 @@ extern int krk_valuesSameOrEqual(KrkValue a, KrkValue b);
|
||||
|
||||
extern KrkValue krk_parse_int(const char * start, size_t width, unsigned int base);
|
||||
|
||||
#ifndef KRK_NO_NAN_BOXING
|
||||
|
||||
typedef union {
|
||||
KrkValue val;
|
||||
double dbl;
|
||||
} KrkValueDbl;
|
||||
|
||||
/*
|
||||
* The following poorly-named macros define bit patterns for identifying
|
||||
* various boxed types.
|
||||
*
|
||||
* Boxing is done by first setting all of the bits of MASK_NAN. If all of
|
||||
* these bits are set, a value is not a float. If any of them are not set,
|
||||
* then a value is a float - and possibly a real NaN.
|
||||
*
|
||||
* Three other bits - one before and two after the MASK_NAN bits - determine
|
||||
* what type the value actually is. KWARGS sets none of the identifying bits,
|
||||
* NONE sets all of them.
|
||||
*/
|
||||
#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_NOTIMPL ((uint64_t)0x7FFE000000000000) /* 0..1110 */
|
||||
#define KRK_VAL_MASK_NAN ((uint64_t)0x7FFC000000000000)
|
||||
#define KRK_VAL_MASK_LOW ((uint64_t)0x0000FFFFFFFFFFFF)
|
||||
|
||||
#ifdef KRK_SANITIZE_OBJECT_POINTERS
|
||||
/**
|
||||
* Debugging tool for verifying we aren't trying to box NULL, which is not a valid object.
|
||||
@ -213,6 +242,47 @@ static inline uintptr_t _krk_sanitize(uintptr_t input) {
|
||||
/* ... and as we said above, if any of the MASK_NAN bits are unset, it's a float. */
|
||||
#define IS_FLOATING(value) (((value) & KRK_VAL_MASK_NAN) != KRK_VAL_MASK_NAN)
|
||||
|
||||
#else
|
||||
|
||||
typedef union {
|
||||
uint64_t val;
|
||||
double dbl;
|
||||
} KrkValueDbl;
|
||||
|
||||
#define NONE_VAL() ((KrkValue){KRK_VAL_NONE,-1})
|
||||
#define NOTIMPL_VAL() ((KrkValue){KRK_VAL_NOTIMPL,0})
|
||||
#define BOOLEAN_VAL(value) ((KrkValue){KRK_VAL_BOOLEAN,!!(value)})
|
||||
#define INTEGER_VAL(value) ((KrkValue){KRK_VAL_INTEGER,((uint64_t)(value)) & 0xFFFFffffFFFFULL})
|
||||
#define KWARGS_VAL(value) ((KrkValue){KRK_VAL_KWARGS,((uint32_t)(value))})
|
||||
#define OBJECT_VAL(value) ((KrkValue){KRK_VAL_OBJECT,((uintptr_t)(value))})
|
||||
#define HANDLER_VAL(ty,ta) ((KrkValue){KRK_VAL_HANDLER,((uint64_t)((((uint64_t)ty) << 32) | ((uint32_t)ta)))})
|
||||
#define FLOATING_VAL(value) ((KrkValue){KRK_VAL_FLOATING,(((KrkValueDbl){.dbl = (value)}).val)})
|
||||
|
||||
#define KRK_VAL_TYPE(value) ((value).tag)
|
||||
|
||||
#define KRK_VAL_MASK_NONE ((uint64_t)0xFFFF000000000000)
|
||||
#define KRK_VAL_MASK_LOW ((uint64_t)0x0000FFFFFFFFFFFF)
|
||||
#define KRK_IX(value) ((uint64_t)((value).val & KRK_VAL_MASK_LOW))
|
||||
#define KRK_SX(value) ((uint64_t)((value).val & 0x800000000000))
|
||||
#define AS_INTEGER(value) ((krk_integer_type)(KRK_SX(value) ? (KRK_IX(value) | KRK_VAL_MASK_NONE) : (KRK_IX(value))))
|
||||
#define AS_BOOLEAN(value) AS_INTEGER(value)
|
||||
|
||||
#define AS_HANDLER(value) ((uint64_t)((value)).val)
|
||||
#define AS_OBJECT(value) ((KrkObj*)((uintptr_t)((value).val)))
|
||||
#define AS_FLOATING(value) (((KrkValueDbl){.val = ((value)).val}).dbl)
|
||||
|
||||
#define IS_INTEGER(value) (!!(((value)).tag & (KRK_VAL_INTEGER|KRK_VAL_BOOLEAN)))
|
||||
#define IS_BOOLEAN(value) (((value)).tag == KRK_VAL_BOOLEAN)
|
||||
#define IS_NONE(value) (((value)).tag == KRK_VAL_NONE)
|
||||
#define IS_HANDLER(value) (((value)).tag == KRK_VAL_HANDLER)
|
||||
#define IS_OBJECT(value) (((value)).tag == KRK_VAL_OBJECT)
|
||||
#define IS_KWARGS(value) (((value)).tag == KRK_VAL_KWARGS)
|
||||
#define IS_NOTIMPL(value) (((value)).tag == KRK_VAL_NOTIMPL)
|
||||
#define IS_FLOATING(value) (((value)).tag == KRK_VAL_FLOATING)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define AS_HANDLER_TYPE(value) (AS_HANDLER(value) >> 32)
|
||||
#define AS_HANDLER_TARGET(value) (AS_HANDLER(value) & 0xFFFFFFFF)
|
||||
#define IS_HANDLER_TYPE(value,type) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == type)
|
||||
|
@ -188,7 +188,7 @@ int krk_parseVArgs(
|
||||
* still want to have all the type checking and automatic parsing. */
|
||||
fmt++;
|
||||
int * out = va_arg(args, int*);
|
||||
*out = arg != KWARGS_VAL(0);
|
||||
*out = !krk_valuesSame(arg, KWARGS_VAL(0));
|
||||
}
|
||||
|
||||
if (*fmt == '!') {
|
||||
@ -198,7 +198,7 @@ int krk_parseVArgs(
|
||||
* Maybe if you want @c p to only be a bool this could be useful? */
|
||||
fmt++;
|
||||
KrkClass * type = va_arg(args, KrkClass*);
|
||||
if (arg != KWARGS_VAL(0) && !krk_isInstanceOf(arg, type)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0)) && !krk_isInstanceOf(arg, type)) {
|
||||
raise_TypeError(_method_name, type ? type->name->chars : "unknown type", arg, names[oarg]);
|
||||
goto _error;
|
||||
}
|
||||
@ -216,7 +216,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'O': {
|
||||
KrkObj ** out = va_arg(args, KrkObj**);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (IS_NONE(arg)) {
|
||||
*out = NULL;
|
||||
} else if (!IS_OBJECT(arg)) {
|
||||
@ -240,7 +240,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'V': {
|
||||
KrkValue * out = va_arg(args, KrkValue*);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
*out = arg;
|
||||
}
|
||||
break;
|
||||
@ -260,8 +260,8 @@ int krk_parseVArgs(
|
||||
fmt++;
|
||||
size = va_arg(args, size_t*);
|
||||
}
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (arg == NONE_VAL()) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (IS_NONE(arg)) {
|
||||
*out = NULL;
|
||||
if (size) *size = 0;
|
||||
} else if (IS_STRING(arg)) {
|
||||
@ -285,7 +285,7 @@ int krk_parseVArgs(
|
||||
fmt++;
|
||||
size = va_arg(args, size_t*);
|
||||
}
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (IS_STRING(arg)) {
|
||||
*out = AS_CSTRING(arg);
|
||||
if (size) *size = AS_STRING(arg)->length;
|
||||
@ -306,7 +306,7 @@ int krk_parseVArgs(
|
||||
* both for future compatibility and to make intent clear, but have no
|
||||
* functional difference at this point.
|
||||
*/
|
||||
#define NUMERIC(c,type) case c: { type * out = va_arg(args, type*); if (arg != KWARGS_VAL(0)) { if (!krk_long_to_int(arg, sizeof(type), out)) goto _error; } break; }
|
||||
#define NUMERIC(c,type) case c: { type * out = va_arg(args, type*); if (!krk_valuesSame(arg, KWARGS_VAL(0))) { if (!krk_long_to_int(arg, sizeof(type), out)) goto _error; } break; }
|
||||
NUMERIC('b',unsigned char)
|
||||
NUMERIC('h',short)
|
||||
NUMERIC('H',unsigned short)
|
||||
@ -325,7 +325,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'C': {
|
||||
int * out = va_arg(args, int*);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (!IS_STRING(arg) || AS_STRING(arg)->codesLength != 1) {
|
||||
raise_TypeError(_method_name, "str of length 1", arg, names[oarg]);
|
||||
goto _error;
|
||||
@ -341,7 +341,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'f': {
|
||||
float * out = va_arg(args, float*);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (!IS_FLOATING(arg)) {
|
||||
KrkClass * type = krk_getType(arg);
|
||||
krk_push(arg);
|
||||
@ -362,7 +362,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'd': {
|
||||
double * out = va_arg(args, double*);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
if (!IS_FLOATING(arg)) {
|
||||
KrkClass * type = krk_getType(arg);
|
||||
krk_push(arg);
|
||||
@ -392,7 +392,7 @@ int krk_parseVArgs(
|
||||
*/
|
||||
case 'p': {
|
||||
int * out = va_arg(args, int*);
|
||||
if (arg != KWARGS_VAL(0)) {
|
||||
if (!krk_valuesSame(arg, KWARGS_VAL(0))) {
|
||||
*out = !krk_isFalsey(arg);
|
||||
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) goto _error;
|
||||
}
|
||||
|
18
src/table.c
18
src/table.c
@ -72,9 +72,9 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue
|
||||
KrkTableEntry * tombstone = NULL;
|
||||
for (;;) {
|
||||
KrkTableEntry * entry = &entries[index];
|
||||
if (entry->key == KWARGS_VAL(0)) {
|
||||
if (krk_valuesSame(entry->key, KWARGS_VAL(0))) {
|
||||
return tombstone != NULL ? tombstone : entry;
|
||||
} else if (entry->key == KWARGS_VAL(1)) {
|
||||
} else if (krk_valuesSame(entry->key, KWARGS_VAL(1))) {
|
||||
if (tombstone == entry) return tombstone;
|
||||
if (tombstone == NULL) tombstone = entry;
|
||||
} else if (krk_valuesSameOrEqual(entry->key, key)) {
|
||||
@ -93,9 +93,9 @@ KrkTableEntry * krk_findEntryExact(KrkTableEntry * entries, size_t capacity, Krk
|
||||
KrkTableEntry * tombstone = NULL;
|
||||
for (;;) {
|
||||
KrkTableEntry * entry = &entries[index];
|
||||
if (entry->key == KWARGS_VAL(0)) {
|
||||
if (krk_valuesSame(entry->key, KWARGS_VAL(0))) {
|
||||
return tombstone != NULL ? tombstone : entry;
|
||||
} else if (entry->key == KWARGS_VAL(1)) {
|
||||
} else if (krk_valuesSame(entry->key, KWARGS_VAL(1))) {
|
||||
if (tombstone == entry) return tombstone;
|
||||
if (tombstone == NULL) tombstone = entry;
|
||||
} else if (krk_valuesSame(entry->key, key)) {
|
||||
@ -192,12 +192,12 @@ int krk_tableGet_fast(KrkTable * table, KrkString * str, KrkValue * value) {
|
||||
KrkTableEntry * tombstone = NULL;
|
||||
for (;;) {
|
||||
KrkTableEntry * entry = &table->entries[index];
|
||||
if (entry->key == KWARGS_VAL(0)) {
|
||||
if (krk_valuesSame(entry->key, KWARGS_VAL(0))) {
|
||||
return 0;
|
||||
} else if (entry->key == KWARGS_VAL(1)) {
|
||||
} else if (krk_valuesSame(entry->key, KWARGS_VAL(1))) {
|
||||
if (tombstone == entry) return 0;
|
||||
if (tombstone == NULL) tombstone = entry;
|
||||
} else if (entry->key == OBJECT_VAL(str)) {
|
||||
} else if (krk_valuesSame(entry->key, OBJECT_VAL(str))) {
|
||||
*value = entry->value;
|
||||
return 1;
|
||||
}
|
||||
@ -236,9 +236,9 @@ KrkString * krk_tableFindString(KrkTable * table, const char * chars, size_t len
|
||||
KrkTableEntry * tombstone = NULL;
|
||||
for (;;) {
|
||||
KrkTableEntry * entry = &table->entries[index];
|
||||
if (entry->key == KWARGS_VAL(0)) {
|
||||
if (krk_valuesSame(entry->key, KWARGS_VAL(0))) {
|
||||
return NULL;
|
||||
} else if (entry->key == KWARGS_VAL(1)) {
|
||||
} else if (krk_valuesSame(entry->key, KWARGS_VAL(1))) {
|
||||
if (tombstone == entry) return NULL;
|
||||
if (tombstone == NULL) tombstone = entry;
|
||||
} else if (AS_STRING(entry->key)->length == length &&
|
||||
|
11
src/value.c
11
src/value.c
@ -30,13 +30,6 @@ void krk_freeValueArray(KrkValueArray * array) {
|
||||
krk_initValueArray(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity really should be the simple...
|
||||
*/
|
||||
int krk_valuesSame(KrkValue a, KrkValue b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
static inline int _krk_method_equivalence(KrkValue a, KrkValue b) {
|
||||
KrkClass * type = krk_getType(a);
|
||||
if (likely(type && type->_eq)) {
|
||||
@ -69,7 +62,7 @@ static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkVa
|
||||
case KRK_VAL_NOTIMPL:
|
||||
case KRK_VAL_KWARGS:
|
||||
case KRK_VAL_HANDLER:
|
||||
return a == b;
|
||||
return krk_valuesSame(a,b);
|
||||
case KRK_VAL_OBJECT:
|
||||
default:
|
||||
return _krk_method_equivalence(a,b);
|
||||
@ -101,7 +94,7 @@ static inline int _krk_diff_type_equivalence(uint16_t val_a, uint16_t val_b, Krk
|
||||
|
||||
_hot
|
||||
int krk_valuesSameOrEqual(KrkValue a, KrkValue b) {
|
||||
if (a == b) return 1;
|
||||
if (krk_valuesSame(a,b)) return 1;
|
||||
uint16_t val_a = KRK_VAL_TYPE(a);
|
||||
uint16_t val_b = KRK_VAL_TYPE(b);
|
||||
return (val_a == val_b)
|
||||
|
12
src/vm.c
12
src/vm.c
@ -1652,7 +1652,7 @@ static void clearCache(KrkClass * type) {
|
||||
type->cacheIndex = 0;
|
||||
for (size_t i = 0; i < type->subclasses.capacity; ++i) {
|
||||
KrkTableEntry * entry = &type->subclasses.entries[i];
|
||||
if (entry->key == KWARGS_VAL(0)) continue;
|
||||
if (krk_valuesSame(entry->key, KWARGS_VAL(0))) continue;
|
||||
clearCache(AS_CLASS(entry->key));
|
||||
}
|
||||
}
|
||||
@ -2448,13 +2448,13 @@ _finishReturn: (void)0;
|
||||
*/
|
||||
case OP_JUMP_IF_FALSE_OR_POP: {
|
||||
TWO_BYTE_OPERAND;
|
||||
if (krk_peek(0) == BOOLEAN_VAL(0) || krk_isFalsey(krk_peek(0))) frame->ip += OPERAND;
|
||||
if (krk_valuesSame(krk_peek(0), BOOLEAN_VAL(0)) || krk_isFalsey(krk_peek(0))) frame->ip += OPERAND;
|
||||
else krk_pop();
|
||||
break;
|
||||
}
|
||||
case OP_POP_JUMP_IF_FALSE: {
|
||||
TWO_BYTE_OPERAND;
|
||||
if (krk_peek(0) == BOOLEAN_VAL(0) || krk_isFalsey(krk_peek(0))) frame->ip += OPERAND;
|
||||
if (krk_valuesSame(krk_peek(0), BOOLEAN_VAL(0)) || krk_isFalsey(krk_peek(0))) frame->ip += OPERAND;
|
||||
krk_pop();
|
||||
break;
|
||||
}
|
||||
@ -2542,7 +2542,7 @@ _finishReturn: (void)0;
|
||||
krk_push(iter);
|
||||
krk_push(krk_callStack(0));
|
||||
/* krk_valuesSame() */
|
||||
if (iter == krk_peek(0)) frame->ip += OPERAND;
|
||||
if (krk_valuesSame(iter, krk_peek(0))) frame->ip += OPERAND;
|
||||
break;
|
||||
}
|
||||
case OP_LOOP_ITER: {
|
||||
@ -2550,12 +2550,12 @@ _finishReturn: (void)0;
|
||||
KrkValue iter = krk_peek(0);
|
||||
krk_push(iter);
|
||||
krk_push(krk_callStack(0));
|
||||
if (iter != krk_peek(0)) frame->ip -= OPERAND;
|
||||
if (!krk_valuesSame(iter, krk_peek(0))) frame->ip -= OPERAND;
|
||||
break;
|
||||
}
|
||||
case OP_TEST_ARG: {
|
||||
TWO_BYTE_OPERAND;
|
||||
if (krk_pop() != KWARGS_VAL(0)) frame->ip += OPERAND;
|
||||
if (!krk_valuesSame(krk_pop(), KWARGS_VAL(0))) frame->ip += OPERAND;
|
||||
break;
|
||||
}
|
||||
case OP_FILTER_EXCEPT: {
|
||||
|
@ -318,7 +318,7 @@ static int doSecondPass(FILE * out) {
|
||||
WRITE_FUNCTION(AS_codeobject(*val));
|
||||
break;
|
||||
default:
|
||||
if (*val == Ellipsis) {
|
||||
if (krk_valuesSame(*val,Ellipsis)) {
|
||||
fwrite("e",1,1,out);
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user