Skip to content

Commit

Permalink
Correctly register a thrower on a surrounding iter, for lambda support
Browse files Browse the repository at this point in the history
  • Loading branch information
hmdne committed Nov 5, 2022
1 parent 479bf7e commit cf64bef
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 4 deletions.
12 changes: 10 additions & 2 deletions lib/opal/nodes/closure.rb
Expand Up @@ -99,6 +99,7 @@ def generate_thrower(type, closure, value)
id = closure.register_catcher(type)
closure.register_thrower(type, id)
push id, '.$throw(', value, ')'
id
end

def generate_thrower_without_catcher(type, closure, value)
Expand All @@ -113,6 +114,7 @@ def generate_thrower_without_catcher(type, closure, value)
closure.register_thrower(type, id)
end
push id, '.$throw(', value, ')'
id
end

def thrower(type, value = nil)
Expand All @@ -133,7 +135,10 @@ def thrower(type, value = nil)
elsif thrower_closure == last_closure
push 'return ', expr_or_nil(value)
else
generate_thrower(:return, thrower_closure, expr_or_nil(value))
id = generate_thrower(:return, thrower_closure, expr_or_nil(value))
# Additionally, register our thrower on the surrounding iter, if present
iter_closure = select_closure(ITER, break_after: DEF | MODULE | TOP)
iter_closure.register_thrower(:return, id) if iter_closure
end
when :eval_return
thrower_closure = select_closure(DEF | LAMBDA, break_after: MODULE | TOP)
Expand Down Expand Up @@ -174,7 +179,10 @@ def thrower(type, value = nil)
push 'break'
end
else
generate_thrower(:break, thrower_closure, expr_or_nil(value))
id = generate_thrower(:break, thrower_closure, expr_or_nil(value))
# Additionally, register our thrower on the surrounding iter, if present
iter_closure = select_closure(ITER, break_after: DEF | MODULE | TOP)
iter_closure.register_thrower(:break, id) if iter_closure
end
when :retry
# TODO: Find the closest RETRIER and Opal.cflow(:retry) (set x to catch it)
Expand Down
1 change: 0 additions & 1 deletion spec/filters/bugs/kernel.rb
Expand Up @@ -316,7 +316,6 @@
fails "Kernel.global_variables finds subset starting with std"
fails "Kernel.lambda does not create lambda-style Procs when captured with #method" # Expected true to be false
fails "Kernel.lambda raises an ArgumentError when no block is given"
fails "Kernel.lambda returns from the lambda itself, not the creation site of the lambda"
fails "Kernel.lambda returns the passed Proc if given an existing Proc through super" # Expected true to be false
fails "Kernel.lambda returns the passed Proc if given an existing Proc" # Expected true to be false
fails "Kernel.loop returns StopIteration#result, the result value of a finished iterator" # requires changes in enumerator.rb
Expand Down
1 change: 0 additions & 1 deletion spec/filters/bugs/method.rb
Expand Up @@ -27,7 +27,6 @@
fails "Method#curry with optional arity argument raises ArgumentError when the method requires less arguments than the given arity"
fails "Method#curry with optional arity argument raises ArgumentError when the method requires more arguments than the given arity"
fails "Method#define_method when passed a Proc object and a method is defined inside defines the nested method in the default definee where the Proc was created" # Expected #<#<Class:0x3753c>:0x37538> NOT to have method 'nested_method_in_proc_for_define_method' but it does
fails "Method#define_method when passed a block behaves exactly like a lambda for break" # Exception: unexpected break
fails "Method#define_method when passed an UnboundMethod object defines a method with the same #arity as the original"
fails "Method#define_method when passed an UnboundMethod object defines a method with the same #parameters as the original"
fails "Method#eql? missing methods returns true for the same method missing"
Expand Down

0 comments on commit cf64bef

Please sign in to comment.