• core核心模块


    5. core核心模块

    • 核心模块会通过compiler模块提供的调用compiler的功能, 将用户的输入转为VM直接的输入

    • 编译模块用来编译, 而核心模块用来执行

    • 在core.h文件中

    // 不需要任何参数, 因为核心模块是在VM内部的, 在buildCore中会将核心模块注册到VM的allModule map中, 并且创建内部的objectclass, objectmetaclass, classofclass类对象, 并为他们绑定方法
    void buildCore(VM *vm);
    VMResult executeModule(VM *vm, Value moduleName, const char *modcode);
    
    • 在core.c文件中(在core.c中实现内部类的方法, 并定义bindMethod的函数并定到class中),方法的参数都是(VM *vm, Value *args), 其中args[0]存的是this或者cls, 方法都会返回值, 在方法中将返回值存放到args[0]中, 这个是脚本语言层面上的返回值表现, 但是在C语言中, 最后一步返回的是bool类型的, true表示没有出错, false表示出错了, 需要切换线程
    // 这些有你自己决定, 可以参考Java的实现
    Object的方法
        PrimObjectNot
        PrimObjectEquals
        PrimObjectToString
        PrimObjectNotEquals
        PrimObjectIs
        
    Class的方法
        PrimClassToString
        PrimClassName
        PrimClassSuperType
        PrimClassMetaSame
        
        // 还要封装defineModuleVar, 实现defineClass函数来定义函数
        // 在哪个模块中, 定义什么名字的变量:-)
        Class *defineClass(vm, module, name) {
            Class *class = newRawClass();
            defineModule(vm, class, ...);
            return class;
        }
        
    // 除了定义方法之外还定义了函数绑定bindMethod, 程序中所有的方法名都注册到vm的方法符号表中
    // 为了方便使用prim_method_bind封装一下bindMethod, bindMethod不管三七二十一就绑定了, 这样显然是不合理的, 使用prim_method_bind封装该函数, 先在vm的methodNames中找, 如果没有则添加进去, 接着在调用bindMethod绑定, --> 伪代码
    // Primitive函数指针的原型为void (Primitive *)(VM *vm, Value *args[0])
    void prim_method_bind(VM *vm, classPtr, const char *method_name, Primitive func) {
        ObjString *objString = newObjString(vm, method_name, strlen(method_name));
        int idx = getIndexFromSymbolTableInVM(vm, objString);
        // 没有找到, 则添加
        if (idx == -1) {
            addSymbolTableInVM(vm, objString);
        }
        Method method;
        method.type = PRIMI_TYPE; // 原生方法
        method.primFn = func;
        bindMethod(vm, classPtr, index, method);
    }
    
    // bindMethod伪代码
    void bindMethod(VM *vm, classPtr, index, method) {
        int idx = index;
        while (idx > classPtr.methodbuffer.count) {
            fillNone(classPtr.methodbuffer, (Value){ValueTypeNull, {0}});
            ++idx;
        }
        classPtr.methodbuffer[idx] = method;
    }
    
    // 关于方法的绑定还要考虑到继承, 继承时需要经父类的methodbuffer拷贝过来
    void bindSuperClass(VM *vm, Class *subclass, Class *superclass) {
        subclass->superclass = superclass;
        subclass->fieldNum += superclass.fieldNum;
        int index = 0;
        while (index < superclass.methodbuffer.count) {
            bindMethod
            ++index;
        }
    }
    
    • 在core.c文件中还要定义其他函数

      • buildCore-> VM在调用newVM的时候就会调用, 该函数会创建coreModule并添加到vm的allModule Map中, 接着创建ObjectClass, ObjectMetaClass, ClassOfClass类对象, 并为他们绑定方法(prim_bind_method)以及绑定父类(bindSuperClass), 这些函数都在上面提到了

      • executeModule->为什么要放在这里, 因为core模块用于执行, 所以executeModule在这里合理, 在executeModule中调用loadModule返回ObjThread, 在loadModule中调compileModule返回ObjFunc对象, 他们都是在core模块运行的, 在compileModule中又会调用compiler模块的compileProgram接口编译

  • 相关阅读:
    bzoj1336: [Balkan2002]Alien最小圆覆盖
    bzoj3564: [SHOI2014]信号增幅仪
    [HDU5353]
    [codeforce1072D]
    [dp001]逛公园
    树上问题泛做
    [BZOJ2599]race
    [CEOI2019]MAGIC TREE
    [BZOJ2836]魔法树
    QTREE3
  • 原文地址:https://www.cnblogs.com/megachen/p/10383670.html
Copyright © 2020-2023  润新知