Skip to content

Commit

Permalink
Compiler: add primitive to get a class' instance type id
Browse files Browse the repository at this point in the history
Useful when overriding allocate to correctly set the type id
  • Loading branch information
asterite committed Dec 14, 2016
1 parent ddc61d7 commit a8fbc2d
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/compiler/crystal/codegen/primitives.cr
Expand Up @@ -47,6 +47,8 @@ class Crystal::CodeGenVisitor
codegen_primitive_object_id node, target_def, call_args
when "object_crystal_type_id"
codegen_primitive_object_crystal_type_id node, target_def, call_args
when "class_crystal_instance_type_id"
codegen_primitive_class_crystal_instance_type_id node, target_def, call_args
when "symbol_to_s"
codegen_primitive_symbol_to_s node, target_def, call_args
when "class"
Expand Down Expand Up @@ -566,6 +568,10 @@ class Crystal::CodeGenVisitor
end
end

def codegen_primitive_class_crystal_instance_type_id(node, target_def, call_args)
type_id(context.type.instance_type)
end

def codegen_primitive_symbol_to_s(node, target_def, call_args)
load(gep @llvm_mod.globals[SYMBOL_TABLE_NAME], int(0), call_args[0])
end
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/crystal/semantic/main_visitor.cr
Expand Up @@ -2175,6 +2175,8 @@ module Crystal
node.type = program.uint64
when "object_crystal_type_id"
node.type = program.int32
when "class_crystal_instance_type_id"
node.type = program.int32
when "symbol_to_s"
node.type = program.string
when "class"
Expand Down
5 changes: 5 additions & 0 deletions src/object.cr
Expand Up @@ -1144,4 +1144,9 @@ class Object
\{% end %}
end
end

protected def self.set_crystal_type_id(ptr)
ptr.as(LibC::SizeT*).value = LibC::SizeT.new(crystal_instance_type_id)
ptr
end
end
6 changes: 6 additions & 0 deletions src/primitives.cr
Expand Up @@ -51,6 +51,12 @@ class Reference
end
end

class Class
@[Primitive(:class_crystal_instance_type_id)]
def crystal_instance_type_id
end
end

struct Bool
# Returns true if *self* is equal to *other*.
@[Primitive(:binary)]
Expand Down
5 changes: 4 additions & 1 deletion src/weak_ref.cr
Expand Up @@ -9,7 +9,10 @@ class WeakRef(T)
end

def self.allocate
GC.malloc_atomic(sizeof(self)).as(self)
ptr = GC.malloc_atomic(sizeof(self)).as(self)
# TODO: uncomment after 0.20.1
# set_crystal_type_id(ptr)
ptr
end

# Returns the referenced object or `Nil` if it has been garbage-collected.
Expand Down

1 comment on commit a8fbc2d

@asterite
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BlaXpirit I finally decided to do it like this, so when overriding allocate you'll have to call set_crystal_type_id(allocate_memory_here). It's just a bit more of work, but overriding allocate shouldn't be that frequently needed.

Please sign in to comment.