码迷,mamicode.com
首页 > 其他好文 > 详细

core核心模块

时间:2019-02-15 15:42:11      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:脚本语言   buffer   输入   mpi   接口   调用   用户   c中   com   

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接口编译

core核心模块

标签:脚本语言   buffer   输入   mpi   接口   调用   用户   c中   com   

原文地址:https://www.cnblogs.com/megachen/p/10383670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!