Как MRI анализирует оператор `|| =`?

Сегодня я пытался объяснить коллеге, что ||= не является потокобезопасным в МРТ. Я решил, что посмотрю на источник Ruby, чтобы попытаться посмотреть, могу ли я указать место, где планировщик Ruby мог бы переключать контекст потока, но у меня возникли проблемы с навигацией по коду. Я надеялся, что кто-то более опытный может пройти меня через файлы, которые попали.

До сих пор я знаю, что Bison берет parse.y и генерирует файл parse.c, который вызывает некоторые базовые функции. Я вижу, что || анализируется как tOROP, но затем я немного теряюсь в том, что происходит дальше

Также есть какой-то инструмент вроде Ripper, который я могу использовать, чтобы сделать этот процесс немного проще? (И на этой ноте было бы полезно, если бы кто-то мог указать мне, где определяется исходный код Ripper)

Ответы

Ответ 1

Забывая синтаксический анализатор, если вы посмотрите на код в compile.c здесь, вы увидите, как генерируются инструкции для обработки задания или. Каждый вызов ADD_INSNL испускает инструкцию. На строке 4553 вы видите условие if, которое проверяет значение LHS после его считывания кодом, испускаемым вызовом макроса COMPILE по строке 4546, чтобы решить, следует ли назначать новое значение. В течение этого времени другой поток может контролировать и изменять прочитанное значение, поэтому назначение выполняется (или не выполняется), когда это не должно быть.

Как для создания NODE_OP_ASGN_OR, обратитесь к вызову NEW_OP_ASGN_OR (определенному в node.h), вызванному из parse.y в функции new_op_assign_gen().

Надеемся, что номера строк не изменятся слишком быстро и недействительны эти URL.