Skip to content

Commit

Permalink
Showing 2 changed files with 21 additions and 3 deletions.
19 changes: 16 additions & 3 deletions src/compiler/crystal/codegen/class_var.cr
Original file line number Diff line number Diff line change
@@ -46,6 +46,18 @@ class Crystal::CodeGenVisitor
def initialize_class_var(owner : ClassVarContainer, name : String, meta_vars : MetaVars, node : ASTNode)
class_var = owner.lookup_class_var(name)

init_function_name = "~#{class_var_global_initialized_name(owner, name)}"

# For unsafe class var we just initialize them without
# using a flag to know if they were initialized
if class_var.uninitialized
global = declare_class_var(owner, name, class_var.type, class_var.thread_local?)
func = @main_mod.functions[init_function_name]? ||
create_initialize_class_var_function(init_function_name, owner, name, class_var.type, class_var.thread_local?, meta_vars, node)
call func
return global
end

global, initialized_flag = declare_class_var_and_initialized_flag(owner, name, class_var.type, class_var.thread_local?)

initialized_block, not_initialized_block = new_blocks "initialized", "not_initialized"
@@ -56,7 +68,6 @@ class Crystal::CodeGenVisitor
position_at_end not_initialized_block
store int1(1), initialized_flag

init_function_name = "~#{class_var_global_initialized_name(owner, name)}"
func = @main_mod.functions[init_function_name]? ||
create_initialize_class_var_function(init_function_name, owner, name, class_var.type, class_var.thread_local?, meta_vars, node)
func = check_main_fun init_function_name, func
@@ -70,7 +81,7 @@ class Crystal::CodeGenVisitor
end

def create_initialize_class_var_function(fun_name, owner, name, type, thread_local, meta_vars, node)
global, initialized_flag = declare_class_var_and_initialized_flag(owner, name, type, thread_local)
global = declare_class_var(owner, name, type, thread_local)

define_main_function(fun_name, ([] of LLVM::Type), LLVM::Void, needs_alloca: true) do |func|
with_cloned_context do
@@ -131,10 +142,12 @@ class Crystal::CodeGenVisitor
end

initializer = class_var.initializer
unless initializer
if !initializer || class_var.uninitialized
return get_global class_var_global_name(class_var.owner, class_var.name), class_var.type, class_var
end

initializer = initializer.not_nil!

read_function_name = "~#{class_var_global_name(class_var.owner, class_var.name)}:read"
func = @main_mod.functions[read_function_name]? ||
create_read_class_var_function(read_function_name, class_var.owner, class_var.name, class_var.type, class_var.thread_local?, initializer.meta_vars, initializer.node)
5 changes: 5 additions & 0 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -258,6 +258,11 @@ module Crystal
else
node.raise "can only declare instance variables of a non-generic class, not a #{type.type_desc} (#{type})"
end
when ClassVar
attributes = check_valid_attributes node, ValidGlobalAttributes, "global variable"

class_var = visit_class_var var
class_var.thread_local = true if Attribute.any?(attributes, "ThreadLocal")
end

node.type = @mod.nil

0 comments on commit 8bd74fe

Please sign in to comment.