Forráskód Böngészése

Include the ivar in the Objective-C class unconditionally of it being used or not.

Allow pseudo-fields for ivar access.
Harold Brenes 5 hónapja
szülő
commit
bca02f81cd
4 módosított fájl, 53 hozzáadás és 24 törlés
  1. 2 3
      src/llvm_backend.cpp
  2. 24 8
      src/llvm_backend_expr.cpp
  3. 18 13
      src/llvm_backend_utility.cpp
  4. 9 0
      src/types.cpp

+ 2 - 3
src/llvm_backend.cpp

@@ -1707,9 +1707,8 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) {
 
         // Add ivar if we have one
         Type *ivar_type = class_type->Named.type_name->TypeName.objc_ivar;
-    	lbObjCGlobal *g_ivar = map_get(&ivar_map, class_type);
 
-        if (ivar_type != nullptr && g_ivar != nullptr) {
+        if (ivar_type != nullptr) {
             // Register a single ivar for this class
             Type *ivar_base = ivar_type->Named.base;
             // TODO(harold): No idea if I can use this, but I assume so?
@@ -1734,7 +1733,7 @@ gb_internal void lb_finalize_objc_names(lbGenerator *gen, lbProcedure *p) {
         lb_emit_runtime_call(p, "objc_registerClassPair", args);
     }
 
-	// Register ivars
+	// Register ivar offsets for any `objc_ivar_get` expressions emitted.
 	Type *ptr_u32 = alloc_type_pointer(t_u32);
 	for (auto const& kv : ivar_map) {
 		lbObjCGlobal const& g = kv.value;

+ 24 - 8
src/llvm_backend_expr.cpp

@@ -5138,8 +5138,6 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
 				return lb_build_addr(p, unparen_expr(se->selector));
 			}
 
-
-			Type *type = base_type(tav.type);
 			if (tav.mode == Addressing_Type) { // Addressing_Type
 				Selection sel = lookup_field(tav.type, selector, true);
 				if (sel.pseudo_field) {
@@ -5174,18 +5172,37 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
 				return lb_addr_swizzle(a, type, swizzle_count, swizzle_indices);
 			}
 
-			Selection sel = lookup_field(type, selector, false);
+			Selection sel = lookup_field(tav.type, selector, false);
 			GB_ASSERT(sel.entity != nullptr);
-			if (sel.pseudo_field) {
-				GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup);
+			if (sel.pseudo_field && (sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup)) {
+				// GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup);
 				Entity *e = entity_of_node(sel_node);
 				GB_ASSERT(e->kind == Entity_Procedure);
 				return lb_addr(lb_find_value_from_entity(p->module, e));
 			}
 
-			if (sel.is_bit_field) {
-				lbAddr addr = lb_build_addr(p, se->expr);
+			lbAddr addr = lb_build_addr(p, se->expr);
+
+			// TODO(harold): Ensure objc_ivar is always null when objc_implement is not set!
+			Type *d_type = type_deref(tav.type); //base_type(tav.type);
+			if (d_type->kind == Type_Named && d_type->Named.type_name->TypeName.objc_ivar) {
+				// NOTE(harold): We need to load the ivar from the current address and
+				//				 replace addr with the loaded ivar addr to apply the selector load properly.
+
+				// If it's a deep pointer, dereference it first
+				// TODO(harold): Ensure this is save to do here. lb_emit_deep_field_gep() has several derefs, once per index.
+				//				 Not sure what multiple indices represent...
+				Type* type = tav.type;
+				if (is_type_pointer(type)) {
+					type = type_deref(type);
+					addr = lb_addr(lb_emit_load(p, addr.addr));
+				}
 
+				lbValue ivar_ptr = lb_handle_objc_ivar_for_objc_object_pointer(p, addr.addr);
+				addr = lb_addr(ivar_ptr);
+			}
+
+			if (sel.is_bit_field) {
 				Selection sub_sel = sel;
 				sub_sel.index.count -= 1;
 
@@ -5211,7 +5228,6 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
 			}
 
 			{
-				lbAddr addr = lb_build_addr(p, se->expr);
 				if (addr.kind == lbAddr_Map) {
 					lbValue v = lb_addr_load(p, addr);
 					lbValue a = lb_address_from_load_or_generate_local(p, v);

+ 18 - 13
src/llvm_backend_utility.cpp

@@ -2191,25 +2191,30 @@ gb_internal lbAddr lb_handle_objc_find_or_register_ivar(lbModule *m, Type *self_
 	return addr;
 }
 
-gb_internal lbValue lb_handle_objc_ivar_get(lbProcedure *p, Ast *expr) {
-    ast_node(ce, CallExpr, expr);
-    lbModule *m = p->module;
+gb_internal lbValue lb_handle_objc_ivar_for_objc_object_pointer(lbProcedure *p, lbValue self) {
+	GB_ASSERT(self.type->kind == Type_Pointer && self.type->Pointer.elem->kind == Type_Named);
 
-    GB_ASSERT(ce->args[0]->tav.type->kind == Type_Pointer);
-    Type *self_type = ce->args[0]->tav.type->Pointer.elem;
-    Type *ivar_type = self_type->Named.type_name->TypeName.objc_ivar;
+	Type *self_type = self.type->Pointer.elem;
+
+	lbValue self_uptr = lb_emit_conv(p, self, t_uintptr);
+
+	lbValue ivar_offset      = lb_addr_load(p, lb_handle_objc_find_or_register_ivar(p->module, self_type));
+	lbValue ivar_offset_uptr = lb_emit_conv(p, ivar_offset, t_uintptr);
 
-    Type* p_ivar = alloc_type_pointer(ivar_type);
 
-    lbValue ivar_offset      = lb_addr_load(p, lb_handle_objc_find_or_register_ivar(m, self_type));
-    lbValue ivar_offset_uptr = lb_emit_conv(p, ivar_offset, t_uintptr);
+	lbValue ivar_uptr = lb_emit_arith(p, Token_Add, self_uptr, ivar_offset_uptr, t_uintptr);
 
-    lbValue self      = lb_build_expr(p, ce->args[0]);
-    lbValue self_uptr = lb_emit_conv(p, self, t_uintptr);
+	Type *ivar_type = self_type->Named.type_name->TypeName.objc_ivar;
+	return lb_emit_conv(p, ivar_uptr, alloc_type_pointer(ivar_type));
+}
 
-    lbValue ivar_uptr = lb_emit_arith(p, Token_Add, self_uptr, ivar_offset_uptr, t_uintptr);
+gb_internal lbValue lb_handle_objc_ivar_get(lbProcedure *p, Ast *expr) {
+    ast_node(ce, CallExpr, expr);
+
+    GB_ASSERT(ce->args[0]->tav.type->kind == Type_Pointer);
+    lbValue self = lb_build_expr(p, ce->args[0]);
 
-    return lb_emit_conv(p, ivar_uptr, p_ivar);
+	return lb_handle_objc_ivar_for_objc_object_pointer(p, self);
 }
 
 gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {

+ 9 - 0
src/types.cpp

@@ -3329,6 +3329,15 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name
 					}
 				}
 			}
+
+			Type *objc_ivar_type = e->TypeName.objc_ivar;
+			if (objc_ivar_type != nullptr) {
+				sel = lookup_field_with_selection(objc_ivar_type, field_name, false, sel, allow_blank_ident);
+				if (sel.entity != nullptr) {
+					sel.pseudo_field = true;
+					return sel;
+				}
+			}
 		}
 
 		if (is_type_polymorphic(type)) {