We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I was trying to implement something like a Ruby send method and get compiler crashed: http://play.crystal-lang.org/#/r/63h
send
module Sendable class WrongNumberOfArguments < Exception def initialize(method, given, expected) super("Wrong number of arguments for '#{method}' (#{given} for #{expected})") end end class WrongInstanceMethod < Exception def initialize(klass, method) super("Instance of '#{klass}' class has no '#{method}' method") end end # Allows to invoke objects methods through 'send' method. macro create_send case method {% methods = @type.methods %} {% for m in methods %} {% args = m.args %} when "{{m.name.id}}" raise WrongNumberOfArguments.new({{m.name.stringify}}, args.length, {{m.args.length}}) unless args.length == {{m.args.length}} {{m.name.id}}{% unless args.empty? %}( {% for arg in args %}{{arg.id}}=args[:{{arg.id}}],{% end %}){% end %} {% end %} else raise WrongInstanceMethod.new({{@type.name.stringify}}, "#{method}") end end def send(method, args={} of Symbol => String) create_send end end class My include Sendable def hello send "bye" end def bye bye end end my = My.new my.send "hello"
Output
; ModuleID = 'My' %String = type { i32, i32, i32, i8 } %My = type { i32 } %"Hash(Symbol, String)" = type { i32, i32, %"Hash(K, V)::Entry(Symbol, String)"**, i32, i32, i1 } %"Hash(K, V)::Entry(Symbol, String)" = type { i32 } %"Sendable::WrongNumberOfArguments" = type { i32, %String*, i1, %"Array(String)"* } %"Array(String)" = type { i32, i32, i32, %String** } @symbol_table = external global [1 x %String*] @str = private constant { i32, i32, i32, [6 x i8] } { i32 1, i32 5, i32 5, [6 x i8] c"hello\00" } @str1 = private constant { i32, i32, i32, [4 x i8] } { i32 1, i32 3, i32 3, [4 x i8] c"bye\00" } define %My* @"*My::new:My"() { alloca: %x = alloca %My* br label %entry entry: ; preds = %alloca %0 = call i8* @__crystal_malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32)) %1 = bitcast i8* %0 to %My* %2 = bitcast %My* %1 to i8* call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32), i32 4, i1 false) %3 = getelementptr inbounds %My* %1, i32 0, i32 0 store i32 76, i32* %3 store %My* %1, %My** %x %4 = load %My** %x %5 = call i1 @"*GC::add_finalizer<My>:Nil"(%My* %4) %6 = load %My** %x ret %My* %6 } declare i8* @__crystal_malloc(i32) ; Function Attrs: nounwind declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0 declare i1 @"*GC::add_finalizer<My>:Nil"(%My*) ; Function Attrs: noreturn define void @"*My@Sendable#send<My, String>:NoReturn"(%My* %self, %String* %method) #1 { alloca: entry: ; No predecessors! %0 = call %"Hash(Symbol, String)"* @"*Hash(Symbol, String)::new<Hash(Symbol, String):Class>:Hash(Symbol, String)"(i32 329) } declare %"Hash(Symbol, String)"* @"*Hash(Symbol, String)::new<Hash(Symbol, String):Class>:Hash(Symbol, String)"(i32) ; Function Attrs: noreturn define void @"*My@Sendable#send<My, String, Hash(Symbol, String)>:NoReturn"(%My* %self, %String* %method, %"Hash(Symbol, String)"* %args) #1 { alloca: entry: ; No predecessors! %0 = call i1 @"*String@Object#===<String, String>:Bool"(%String* bitcast ({ i32, i32, i32, [6 x i8] }* @str to %String*), %String* %method) br i1 %0, label %then, label %else then: ; preds = %entry %1 = call i32 @"*Hash(Symbol, String)@Hash(K, V)#length<Hash(Symbol, String)>:Int32"(%"Hash(Symbol, String)"* %args) %2 = icmp eq i32 %1, 0 br i1 %2, label %then1, label %else2 else: ; preds = %entry %3 = call i1 @"*String@Object#===<String, String>:Bool"(%String* bitcast ({ i32, i32, i32, [4 x i8] }* @str1 to %String*), %String* %method) br i1 %3, label %then3, label %else4 then1: ; preds = %then br label %exit else2: ; preds = %then %4 = call i32 @"*Hash(Symbol, String)@Hash(K, V)#length<Hash(Symbol, String)>:Int32"(%"Hash(Symbol, String)"* %args) %5 = call %"Sendable::WrongNumberOfArguments"* @"*Sendable::WrongNumberOfArguments::new<String, Int32, Int32>:Sendable::WrongNumberOfArguments"(%String* bitcast ({ i32, i32, i32, [6 x i8] }* @str to %String*), i32 %4, i32 0) call void @"*raise<Sendable::WrongNumberOfArguments>:NoReturn"(%"Sendable::WrongNumberOfArguments"* %5) unreachable exit: ; preds = %then1 call void @"*My#hello<My>:NoReturn"(%My* %self) unreachable then3: ; preds = %else %6 = call i32 @"*Hash(Symbol, String)@Hash(K, V)#length<Hash(Symbol, String)>:Int32"(%"Hash(Symbol, String)"* %args) %7 = icmp eq i32 %6, 0 br i1 %7, label %then5, label %else6 else4: ; preds = %else then5: ; preds = %then3 br label %exit7 else6: ; preds = %then3 %8 = call i32 @"*Hash(Symbol, String)@Hash(K, V)#length<Hash(Symbol, String)>:Int32"(%"Hash(Symbol, String)"* %args) %9 = call %"Sendable::WrongNumberOfArguments"* @"*Sendable::WrongNumberOfArguments::new<String, Int32, Int32>:Sendable::WrongNumberOfArguments"(%String* bitcast ({ i32, i32, i32, [4 x i8] }* @str1 to %String*), i32 %8, i32 0) call void @"*raise<Sendable::WrongNumberOfArguments>:NoReturn"(%"Sendable::WrongNumberOfArguments"* %9) unreachable exit7: ; preds = %then5 } declare i1 @"*String@Object#===<String, String>:Bool"(%String*, %String*) declare i32 @"*Hash(Symbol, String)@Hash(K, V)#length<Hash(Symbol, String)>:Int32"(%"Hash(Symbol, String)"*) declare %"Sendable::WrongNumberOfArguments"* @"*Sendable::WrongNumberOfArguments::new<String, Int32, Int32>:Sendable::WrongNumberOfArguments"(%String*, i32, i32) declare void @"*raise<Sendable::WrongNumberOfArguments>:NoReturn"(%"Sendable::WrongNumberOfArguments"*) ; Function Attrs: noreturn define void @"*My#hello<My>:NoReturn"(%My* %self) #1 { entry: call void @"*My@Sendable#send<My, String>:NoReturn"(%My* %self, %String* bitcast ({ i32, i32, i32, [4 x i8] }* @str1 to %String*)) unreachable } attributes #0 = { nounwind } attributes #1 = { noreturn }
case method when "hello" raise WrongNumberOfArguments.new("hello", args.length, 0) unless args.length == 0 hello when "bye" raise WrongNumberOfArguments.new("bye", args.length, 0) unless args.length == 0 bye else raise WrongInstanceMethod.new("My", "#{method}") end Nil assertion failed _init +171007 [0] _init +173755 [0] _init +3251488 [0] _init +3247103 [0] _init +3244025 [0] _init +3282759 [0] _init +3188090 [0] _init +3188388 [0] _init +3266960 [0] _init +3193184 [0] _init +3266960 [0] _init +3193215 [0] _init +3248139 [0] _init +3244025 [0] _init +3282759 [0] _init +3188090 [0] _init +3248139 [0] _init +3244025 [0] _init +3282759 [0] _init +3188090 [0] _init +3065700 [0] _init +3052068 [0] _init +2396865 [0] _init +5900354 [0] _init +5879350 [0] __libc_start_main +247 [0] _init +167975 [0] Error: you've found a bug in the Crystal compiler. Please open an issue: https://github.com/manastech/crystal/issues
The text was updated successfully, but these errors were encountered:
This happens when bye calls itself ( it's my typo, I mean p "bye" ):
p "bye"
def bye bye end
Sorry, something went wrong.
The above is actually a stack overflow, so duplicate of #271
No branches or pull requests
I was trying to implement something like a Ruby
send
method and get compiler crashed:http://play.crystal-lang.org/#/r/63h
Output
The text was updated successfully, but these errors were encountered: