static PrimitiveResult callFn(WrenVM* vm, Value* args, int numArgs) { ObjFn* fn; if (IS_CLOSURE(args[0])) { fn = AS_CLOSURE(args[0])->fn; } else { fn = AS_FN(args[0]); } if (numArgs < fn->arity) RETURN_ERROR("Function expects more arguments."); return PRIM_CALL; }
void metaCompile(WrenVM* vm) { // Evaluate the code in the module where the calling function was defined. // That's one stack frame back from the top since the top-most frame is the // helper eval() method in Meta itself. Value callingFn = OBJ_VAL(vm->fiber->frames[vm->fiber->numFrames - 2].fn); ObjModule* module = IS_FN(callingFn) ? AS_FN(callingFn)->module : AS_CLOSURE(callingFn)->fn->module; // Compile it. ObjFn* fn = wrenCompile(vm, module, wrenGetArgumentString(vm, 1), false); if (fn == NULL) return; // Return the result. We can't use the public API for this since we have a // bare ObjFn. *vm->foreignCallSlot = OBJ_VAL(fn); vm->foreignCallSlot = NULL; }
static void bindMethod(WrenVM* vm, int methodType, int symbol, ObjClass* classObj, Value methodValue) { ObjFn* methodFn = IS_FN(methodValue) ? AS_FN(methodValue) : AS_CLOSURE(methodValue)->fn; // Methods are always bound against the class, and not the metaclass, even // for static methods, so that constructors (which are static) get bound like // instance methods. wrenBindMethodCode(classObj, methodFn); Method method; method.type = METHOD_BLOCK; method.fn.obj = AS_OBJ(methodValue); if (methodType == CODE_METHOD_STATIC) { classObj = classObj->obj.classObj; } wrenBindMethod(vm, classObj, symbol, method); }