예제 #1
0
        public static ObjBoundMethod newBoundMethod(Value_t receiver, ObjClosure method)
        {
            ObjBoundMethod bound = (ObjBoundMethod)ALLOCATE_OBJ(ObjType.OBJ_BOUND_METHOD);

            bound.receiver = receiver;
            bound.method   = method;
            return(bound);
        }
예제 #2
0
        private static bool callValue(Value_t callee, int argCount)
        {
            if (Value.IS_OBJ(callee))
            {
                ObjType _type = Object.OBJ_TYPE(callee);

                switch (Object.OBJ_TYPE(callee))
                {
                case ObjType.OBJ_BOUND_METHOD:
                {
                    ObjBoundMethod bound = Object.AS_BOUND_METHOD(callee);
                    vm.stack[vm.stackTop - argCount - 1] = bound.receiver;
                    return(call(bound.method, argCount));
                }

                case ObjType.OBJ_CLASS:
                {
                    ObjClass klass = Object.AS_CLASS(callee);
                    vm.stack[vm.stackTop - argCount - 1] = Value.OBJ_VAL(Object.newInstance(klass));
                    Value_t initializer = new Value_t();
                    if (Table.tableGet(ref klass.methods, vm.initString, ref initializer))
                    {
                        return(call(Object.AS_CLOSURE(initializer), argCount));
                    }
                    else if (argCount != 0)
                    {
                        runtimeError("Expected 0 arguments but got {0}.", argCount.ToString());
                        return(false);
                    }
                    vm.frames[vm.frameCount - 1]._ip_index += 2;         // HACK FIX
                    return(true);
                }

                case ObjType.OBJ_CLOSURE:
                    return(call(Object.AS_CLOSURE(callee), argCount));

                case ObjType.OBJ_NATIVE:
                {
                    NativeFn native = Object.AS_NATIVE(callee);
                    Value_t  result = native(argCount, vm.stackTop - argCount);
                    vm.stackTop -= argCount + 1;
                    push(result);

                    vm.frames[vm.frameCount - 1]._ip_index += 2;         // HACK FIX
                    return(true);
                }

                default:
                    // Non-callable object type.
                    break;
                }
            }

            runtimeError("Can only call functions and classes.");
            return(false);
        }
예제 #3
0
        // Generics, <T>, doesn't seem to work with classes?
        static Obj allocateObject(int size, ObjType type)
        {
            Obj object_ = null;

            switch (type)
            {
            case ObjType.OBJ_STRING:
                object_ = new ObjString();
                break;

            case ObjType.OBJ_FUNCTION:
                object_ = new ObjFunction();
                break;

            case ObjType.OBJ_INSTANCE:
                object_ = new ObjInstance();
                break;

            case ObjType.OBJ_NATIVE:
                object_ = new ObjNative();
                break;

            case ObjType.OBJ_CLOSURE:
                object_ = new ObjClosure();
                break;

            case ObjType.OBJ_UPVALUE:
                object_ = new ObjUpvalue();
                break;

            case ObjType.OBJ_CLASS:
                object_ = new ObjClass();
                break;

            case ObjType.OBJ_BOUND_METHOD:
                object_ = new ObjBoundMethod();
                break;

            default:
                object_ = null;    // clox: (Obj*)reallocate(NULL, 0, size);
                break;
            }

            object_.type     = type;
            object_.isMarked = false;

            object_.next  = VM.vm.objects;
            VM.vm.objects = object_;

#if DEBUG_LOG_GC
            System.Console.WriteLine("{0} allocate {1} for {2}", object_._mem_id.ToString(), size.ToString(), type.ToString());
#endif
            return(object_);
        }
예제 #4
0
        private static bool bindMethod(ObjClass klass, ObjString name)
        {
            Value_t method = new Value_t();

            if (!Table.tableGet(ref klass.methods, name, ref method))
            {
                runtimeError("Undefined property '{0}'.", new string(name.chars, 0, name.chars.Length - 1));
                return(false);
            }

            ObjBoundMethod bound = Object.newBoundMethod(peek(0), Object.AS_CLOSURE(method));

            pop();
            push(Value.OBJ_VAL(bound));
            return(true);
        }
예제 #5
0
        private static void blackenObject(Obj object_)
        {
#if DEBUG_LOG_GC
            System.Console.Write("{0} blacken ", object_._mem_id.ToString());
            Value.printValue(Value.OBJ_VAL(object_));
            System.Console.WriteLine();
#endif

            switch (object_.type)
            {
            case ObjType.OBJ_BOUND_METHOD:
            {
                ObjBoundMethod bound = (ObjBoundMethod)object_;
                markValue(ref bound.receiver);
                markObject((Obj)bound.method);
                break;
            }

            case ObjType.OBJ_CLASS:
            {
                ObjClass klass = (ObjClass)object_;
                markObject((Obj)klass.name);
                Table.markTable(ref klass.methods);
                break;
            }

            case ObjType.OBJ_CLOSURE:
            {
                ObjClosure closure = (ObjClosure)object_;
                markObject((Obj)closure.function);
                for (int i = 0; i < closure.upvalueCount; i++)
                {
                    markObject((Obj)closure.upvalues[i]);
                }
                break;
            }

            case ObjType.OBJ_FUNCTION:
            {
                ObjFunction function = (ObjFunction)object_;
                markObject((Obj)function.name);
                markArray(ref function.chunk.constants);
                break;
            }

            case ObjType.OBJ_INSTANCE:
            {
                ObjInstance instance = (ObjInstance)object_;
                markObject((Obj)(instance.klass));
                Table.markTable(ref instance.fields);
                break;
            }

            case ObjType.OBJ_UPVALUE:
                markValue(ref ((ObjUpvalue)object_).closed);
                break;

            case ObjType.OBJ_NATIVE:
            case ObjType.OBJ_STRING:
                break;
            }
        }