Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does MRI parse the `||=` operator?

Tags:

ruby

Today I was trying to explain to a coworker that ||= is not thread-safe in MRI. I figured I'd take a look at the Ruby source to try and see if I could point out the spot where Ruby scheduler could switch the thread context, but I'm having trouble navigating the code. I was hoping someone more experienced could walk me through the files that are hit.

So far I know that Bison takes the parse.y and generates a parse.c file which calls some underlying functions. I see that || is parsed as tOROP but then I get a bit lost on what happens next

Also is there some tool like Ripper that I can use to make this process a little easier? (And on that note it would be helpful if someone could point me to where the Ripper source code is defined)

like image 782
Josh Bodah Avatar asked Sep 10 '15 17:09

Josh Bodah


1 Answers

Forgetting the parser, if you look at the code in compile.c here you'll see how the instructions are generated to handle the assignment-or operation. Each call to ADD_INSNL emits an instruction. At line 4553 you see an if condition, which tests the value of the LHS after it was read by code emitted via the call to the COMPILE macro at line 4546, in order to decide whether to assign the new value. During this time, another thread may supervene and change the value that was read, so the assignment is done (or not done) when it shouldn't be.

As for how the NODE_OP_ASGN_OR is created, see the call to NEW_OP_ASGN_OR (defined in node.h) called from parse.y in function new_op_assign_gen().

Hopefully the line numbers won't change too soon, and invalidate these URLs.

like image 146
cliffordheath Avatar answered Oct 29 '22 21:10

cliffordheath