summaryrefslogtreecommitdiff
path: root/py/emitcommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitcommon.c')
-rw-r--r--py/emitcommon.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/py/emitcommon.c b/py/emitcommon.c
index 02f96f111..679ef1d97 100644
--- a/py/emitcommon.c
+++ b/py/emitcommon.c
@@ -27,6 +27,7 @@
#include <assert.h>
#include "py/emit.h"
+#include "py/nativeglue.h"
#if MICROPY_ENABLE_COMPILER
@@ -40,6 +41,51 @@ qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) {
}
#endif
+// Compare two objects for strict equality, including equality of type. This is
+// different to the semantics of mp_obj_equal which, eg, has (True,) == (1.0,).
+static bool strictly_equal(mp_obj_t a, mp_obj_t b) {
+ if (a == b) {
+ return true;
+ }
+
+ #if MICROPY_EMIT_NATIVE
+ if (a == MP_OBJ_FROM_PTR(&mp_fun_table) || b == MP_OBJ_FROM_PTR(&mp_fun_table)) {
+ return false;
+ }
+ #endif
+
+ const mp_obj_type_t *a_type = mp_obj_get_type(a);
+ const mp_obj_type_t *b_type = mp_obj_get_type(b);
+ if (a_type != b_type) {
+ return false;
+ }
+ if (a_type == &mp_type_tuple) {
+ mp_obj_tuple_t *a_tuple = MP_OBJ_TO_PTR(a);
+ mp_obj_tuple_t *b_tuple = MP_OBJ_TO_PTR(b);
+ if (a_tuple->len != b_tuple->len) {
+ return false;
+ }
+ for (size_t i = 0; i < a_tuple->len; ++i) {
+ if (!strictly_equal(a_tuple->items[i], b_tuple->items[i])) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return mp_obj_equal(a, b);
+ }
+}
+
+size_t mp_emit_common_use_const_obj(mp_emit_common_t *emit, mp_obj_t const_obj) {
+ for (size_t i = 0; i < emit->const_obj_list.len; ++i) {
+ if (strictly_equal(emit->const_obj_list.items[i], const_obj)) {
+ return i;
+ }
+ }
+ mp_obj_list_append(MP_OBJ_FROM_PTR(&emit->const_obj_list), const_obj);
+ return emit->const_obj_list.len - 1;
+}
+
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst) {
// name adding/lookup
id_info_t *id = scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);