value.c
1 #include <limits.h>
2 #include <string.h>
3 #include <kuroko/memory.h>
4 #include <kuroko/value.h>
5 #include <kuroko/object.h>
6 #include <kuroko/vm.h>
7 #include <kuroko/util.h>
8 
9 #include "opcode_enum.h"
10 
12  array->values = NULL;
13  array->capacity = 0;
14  array->count = 0;
15 }
16 
18  if (array->capacity < array->count + 1) {
19  int old = array->capacity;
20  array->capacity = KRK_GROW_CAPACITY(old);
21  array->values = KRK_GROW_ARRAY(KrkValue, array->values, old, array->capacity);
22  }
23 
24  array->values[array->count] = value;
25  array->count++;
26 }
27 
29  KRK_FREE_ARRAY(KrkValue, array->values, array->capacity);
30  krk_initValueArray(array);
31 }
32 
33 static inline int _krk_method_equivalence(KrkValue a, KrkValue b) {
34  KrkClass * type = krk_getType(a);
35  if (likely(type && type->_eq)) {
36  krk_push(a);
37  krk_push(b);
38  KrkValue result = krk_callDirect(type->_eq,2);
39  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 0;
40  if (IS_BOOLEAN(result)) return AS_BOOLEAN(result);
41  if (!IS_NOTIMPL(result)) return !krk_isFalsey(result);
42  }
43 
44  type = krk_getType(b);
45  if (type && type->_eq) {
46  krk_push(b);
47  krk_push(a);
48  KrkValue result = krk_callDirect(type->_eq,2);
49  if (unlikely(krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) return 0;
50  if (IS_BOOLEAN(result)) return AS_BOOLEAN(result);
51  if (!IS_NOTIMPL(result)) return !krk_isFalsey(result);
52  }
53 
54  return 0;
55 }
56 
57 static inline int _krk_same_type_equivalence(uint16_t valtype, KrkValue a, KrkValue b) {
58  switch (valtype) {
59  case KRK_VAL_BOOLEAN:
60  case KRK_VAL_INTEGER:
61  case KRK_VAL_NONE:
62  case KRK_VAL_NOTIMPL:
63  case KRK_VAL_KWARGS:
64  case KRK_VAL_HANDLER:
65  return krk_valuesSame(a,b);
66  case KRK_VAL_OBJECT:
67  default:
68  return _krk_method_equivalence(a,b);
69  }
70 }
71 
72 static inline int _krk_same_type_equivalence_b(uint16_t valtype, KrkValue a, KrkValue b) {
73  switch (valtype) {
74  case KRK_VAL_BOOLEAN:
75  case KRK_VAL_INTEGER:
76  case KRK_VAL_NONE:
77  case KRK_VAL_NOTIMPL:
78  case KRK_VAL_KWARGS:
79  case KRK_VAL_HANDLER:
80  return 0;
81  case KRK_VAL_OBJECT:
82  default:
83  return _krk_method_equivalence(a,b);
84  }
85 }
86 
87 static inline int _krk_diff_type_equivalence(uint16_t val_a, uint16_t val_b, KrkValue a, KrkValue b) {
88  /* We do not want to let KWARGS leak to anything needs to, eg., examine types. */
89  if (val_b == KRK_VAL_KWARGS || val_a == KRK_VAL_KWARGS) return 0;
90 
91  /* Fall back to methods */
92  return _krk_method_equivalence(a,b);
93 }
94 
95 _hot
97  if (krk_valuesSame(a,b)) return 1;
98  uint16_t val_a = KRK_VAL_TYPE(a);
99  uint16_t val_b = KRK_VAL_TYPE(b);
100  return (val_a == val_b)
101  ? _krk_same_type_equivalence_b(val_a, a, b)
102  : _krk_diff_type_equivalence(val_a, val_b, a, b);
103 }
104 
105 _hot
107  uint16_t val_a = KRK_VAL_TYPE(a);
108  uint16_t val_b = KRK_VAL_TYPE(b);
109  return (val_a == val_b)
110  ? _krk_same_type_equivalence(val_a,a,b)
111  : _krk_diff_type_equivalence(val_a,val_b,a,b);
112 }
Functions for dealing with garbage collection and memory allocation.
Struct definitions for core object types.
Type object.
Definition: object.h:215
KrkObj * _eq
__eq__ Implementation for equality check (==)
Definition: object.h:233
int flags
Definition: vm.h:165
Flexible vector of stack references.
Definition: value.h:75
size_t capacity
Definition: value.h:76
KrkValue * values
Definition: value.h:78
void krk_initValueArray(KrkValueArray *array)
Initialize a value array.
Definition: value.c:11
void krk_freeValueArray(KrkValueArray *array)
Release relesources used by a value array.
Definition: value.c:28
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Definition: value.c:17
size_t count
Definition: value.h:77
Stack reference or primative value.
int krk_valuesEqual(KrkValue a, KrkValue b)
Compare two values for equality.
Definition: value.c:106
KrkClass * krk_getType(KrkValue value)
Get the class representing a value.
Definition: vm.c:240
static int krk_valuesSame(KrkValue a, KrkValue b)
Compare two values by identity.
Definition: value.h:141
int krk_valuesSameOrEqual(KrkValue a, KrkValue b)
Compare two values by identity, then by equality.
Definition: value.c:96
int krk_isFalsey(KrkValue value)
Determine the truth of a value.
Definition: vm.c:821
Utilities for creating native bindings.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
krk_threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:118
KrkValue krk_callDirect(KrkObj *callable, int argCount)
Call a closure or native function with argCount arguments.
Definition: vm.c:740