Hello World가 뭐야~ 1장~

14023 단어 Ruby
며칠 전 메이츠의 루비 생일 비화를 들었는데 헬로월드가 나오기까지 반년이 걸렸다고 한다.
그 촉발에 자기도 언어 Hello World 만들어!이렇게 말하지만 기사를 조금 쓰려면 시간적으로 엄격하기 때문에 루비에서 헬로월드의 출력 과정이 어떤 흐름인지 먼저 찾아보고 싶어요.
하지만 솔직히 한눈에 풀리는 건 아니니까 이 기사에서 입구를 정리한 뒤 2장 이후에 노력하겠다.

컨디션

  • Ruby: v2_7_0_rc2
  • main 함수부터 찾기


    처리의 입구부터 가고main 함수부터 모색해 보세요.
    그리고 나서
    main.c
    int
    main(int argc, char **argv)
    {
    #ifdef RUBY_DEBUG_ENV
        ruby_set_debug_option(getenv("RUBY_DEBUG"));
    #endif
    #ifdef HAVE_LOCALE_H
        setlocale(LC_CTYPE, "");
    #endif
    
        ruby_sysinit(&argc, &argv);
        {
        RUBY_INIT_STACK;
        ruby_init();
        return ruby_run_node(ruby_options(argc, argv));
        }
    }
    



    vm_exec.h
    static VALUE
    vm_exec_core(rb_execution_context_t *ec, VALUE initial)
    {
    
    #if OPT_STACK_CACHING
    #if 0
    #elif __GNUC__ && __x86_64__
        DECL_SC_REG(VALUE, a, "12");
        DECL_SC_REG(VALUE, b, "13");
    #else
        register VALUE reg_a;
        register VALUE reg_b;
    #endif
    #endif
    
    #if defined(__GNUC__) && defined(__i386__)
        DECL_SC_REG(const VALUE *, pc, "di");
        DECL_SC_REG(rb_control_frame_t *, cfp, "si");
    #define USE_MACHINE_REGS 1
    
    #elif defined(__GNUC__) && defined(__x86_64__)
        DECL_SC_REG(const VALUE *, pc, "14");
        DECL_SC_REG(rb_control_frame_t *, cfp, "15");
    #define USE_MACHINE_REGS 1
    
    #elif defined(__GNUC__) && defined(__powerpc64__)
        DECL_SC_REG(const VALUE *, pc, "14");
        DECL_SC_REG(rb_control_frame_t *, cfp, "15");
    #define USE_MACHINE_REGS 1
    
    #else
        register rb_control_frame_t *reg_cfp;
        const VALUE *reg_pc;
    #endif
    
    #if USE_MACHINE_REGS
    
    #undef  RESTORE_REGS
    #define RESTORE_REGS() \
    { \
      VM_REG_CFP = ec->cfp; \
      reg_pc  = reg_cfp->pc; \
    }
    
    #undef  VM_REG_PC
    #define VM_REG_PC reg_pc
    #undef  GET_PC
    #define GET_PC() (reg_pc)
    #undef  SET_PC
    #define SET_PC(x) (reg_cfp->pc = VM_REG_PC = (x))
    #endif
    
    #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
    #include "vmtc.inc"
        if (UNLIKELY(ec == 0)) {
        return (VALUE)insns_address_table;
        }
    #endif
        reg_cfp = ec->cfp;
        reg_pc = reg_cfp->pc;
    
    #if OPT_STACK_CACHING
        reg_a = initial;
        reg_b = 0;
    #endif
    
      first:
        INSN_DISPATCH();
    /*****************/
     #include "vm.inc"
    /*****************/
        END_INSNS_DISPATCH();
    
        /* unreachable */
        rb_bug("vm_eval: unreachable");
        goto first;
    }
    
    vm_exec_코어에 도착했을 때 어떻게 발굴해야 할지 몰라서 이 노선을 잠시 취소했습니다.
    vm은 Virtual Machine의 약칭이죠?해석기 언어라도 실현 과정에서 vm의 긴장 상태를 유지하고 이해할지 이해하지 못할지 모르는 상태에서 다음 방법을 계속 진행한다.

    Ruby 객체를 나타낼 위치를 지정합니다.


    서류를 한 번 보았다
    object.c
    VALUE rb_cBasicObject; /*!< BasicObject class */
    VALUE rb_mKernel; /*!< Kernel module */
    VALUE rb_cObject; /*!< Object class */
    VALUE rb_cModule; /*!< Module class */
    VALUE rb_cClass; /*!< Class class */
    VALUE rb_cData; /*!< Data class */
    
    VALUE rb_cNilClass; /*!< NilClass class */
    VALUE rb_cTrueClass; /*!< TrueClass class */
    VALUE rb_cFalseClass; /*!< FalseClass class */
    
    이런 걸 발견했어!그거 닮았어.
    이것은 최소한의 종류의 정의입니까?약간 감동!
    뭐, 그럼 됐어. 목표가 없는 스트링형이니까 계속 읽어.
    여기서는 원래string이라는 이름으로 파일 이름을 검색하지 않았습니까?그래서 해봤어요.

    있다 없다
    그리고 안을 봤어요.
    string.c
    static VALUE
    str_new0(VALUE klass, const char *ptr, long len, int termlen)
    {
        VALUE str;
    
        if (len < 0) {
        rb_raise(rb_eArgError, "negative string size (or size too big)");
        }
    
        RUBY_DTRACE_CREATE_HOOK(STRING, len);
    
        str = str_alloc(klass);
        if (!STR_EMBEDDABLE_P(len, termlen)) {
        RSTRING(str)->as.heap.aux.capa = len;
        RSTRING(str)->as.heap.ptr = ALLOC_N(char, (size_t)len + termlen);
        STR_SET_NOEMBED(str);
        }
        else if (len == 0) {
        ENC_CODERANGE_SET(str, ENC_CODERANGE_7BIT);
        }
        if (ptr) {
        memcpy(RSTRING_PTR(str), ptr, len);
        }
        STR_SET_LEN(str, len);
        TERM_FILL(RSTRING_PTR(str) + len, termlen);
        return str;
    }
    
    있다!
    다만 이 방법은 현재 직접 사용하지 않은 것 같고, 지금은 rb_str_new2라는 방법을 사용한 것 같다.
    그럼 이 방법이 호칭되는 곳부터 거슬러 올라가면 되는 거죠?그렇게 생각하지만 여전히 여기서 교착 상태에 빠져 있다.
    앞이 길어질 것 같아서 1장은 여기서 끝난다.
    제2장 기분이 좋으면 쓰세요.

    좋은 웹페이지 즐겨찾기