Ejemplo n.º 1
0
        /// <summary>
        /// methode permet d'executer les commande
        /// </summary>
        /// <param name="type"></param>
        /// <param name="Entitee"></param>
        /// <param name="CommandeSql"></param>
        /// <returns></returns>
        public void ExecuterCommande(TypeCommande type, ObjClass Entitee, string CommandeSql)
        {
            switch (type)
            {
            case TypeCommande.ExecuteReader:

                break;

            //case TypeCommande.ExecuteScalar:
            // break;

            case TypeCommande.ExecuteNonQuery:

                break;

            default:
                break;
            }

            switch (Entitee)
            {
            case ObjClass.Client:
                break;

            case ObjClass.Fournisseur:
                break;

            default:
                break;
            }
        }
Ejemplo n.º 2
0
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("timer", "timer", _timerSource);
            ObjClass timer = (ObjClass)vm.FindVariable("timer", "Timer");

            vm.Primitive(timer.ClassObj, "startTimer_(_,_)", StartTimer);
        }
Ejemplo n.º 3
0
        // Defines [methodValue] as a method on [classObj].
        private static bool BindMethod(bool isStatic, int symbol, ObjClass classObj, Obj methodContainer)
        {
            // If we are binding a foreign method, just return, as this will be handled later
            if (methodContainer is ObjString)
            {
                return(true);
            }

            ObjFn methodFn = methodContainer as ObjFn ?? ((ObjClosure)methodContainer).Function;

            Method method = new Method {
                MType = MethodType.Block, Obj = methodContainer
            };

            if (isStatic)
            {
                classObj = classObj.ClassObj;
            }

            // Methods are always bound against the class, and not the metaclass, even
            // for static methods, because static methods don't have instance fields
            // anyway.
            Compiler.BindMethodCode(classObj, methodFn);

            classObj.BindMethod(symbol, method);
            return(true);
        }
    static void Main()
    {
        ObjStruct[] array = new ObjStruct[10];
        Console.WriteLine(array[0].Test);

        ObjClass[] array = new ObjClass[10];
        Console.WriteLine(array[0].Test);     //NullReferenceException
    }
Ejemplo n.º 5
0
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("scheduler", "scheduler", _schedulerSource);
            ObjClass scheduler = (ObjClass)vm.FindVariable("scheduler", "Scheduler");

            vm.Primitive(scheduler.ClassObj, "captureMethods_()", CaptureMethods);
            vm.Interpret("scheduler", "scheduler", "Scheduler.captureMethods_()");
        }
Ejemplo n.º 6
0
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("", "", MetaLibSource);

            ObjClass meta = (ObjClass)vm.FindVariable("Meta");

            vm.Primitive(meta.ClassObj, "eval(_)", Eval);
        }
Ejemplo n.º 7
0
        // Creates a new instance of the given [classObj].
        public ObjInstance(ObjClass classObj)
        {
            Fields = new Obj[classObj.NumFields];

            // Initialize fields to null.
            for (int i = 0; i < classObj.NumFields; i++)
            {
                Fields[i] = Null;
            }
            ClassObj = classObj;
        }
Ejemplo n.º 8
0
        public void Primitive(ObjClass objClass, string s, Primitive func)
        {
            if (!MethodNames.Contains(s))
            {
                MethodNames.Add(s);
            }
            int symbol = MethodNames.IndexOf(s);

            objClass.BindMethod(symbol, new Method {
                Primitive = func, MType = MethodType.Primitive
            });
        }
    public CrimeSceneObject(Transform crimeObject, ObjClass classification)
    {
        obj = crimeObject;
        objClassification = classification;
        if (crimeObject.Find("ID").GetComponent <ID>() != null)
        {
            ID objectID = crimeObject.Find("ID").GetComponent <ID>();

            projectName = objectID.RelevantProjectName;
            sceneName   = objectID.RelevantCrimeSceneName;
        }
    }
Ejemplo n.º 10
0
        public void Call(ObjClass objClass, string s)
        {
            if (!MethodNames.Contains(s))
            {
                MethodNames.Add(s);
            }
            int symbol = MethodNames.IndexOf(s);

            objClass.BindMethod(symbol, new Method {
                MType = MethodType.Call
            });
        }
Ejemplo n.º 11
0
        public static void LoadLibrary(WrenVM vm)
        {
            vm.Interpret("io", "io", IoSource);
            ObjClass file = (ObjClass)vm.FindVariable("io", "File");

            vm.Primitive(file.ClassObj, "open_(_,_)", Open);
            vm.Primitive(file.ClassObj, "sizePath_(_,_)", SizePath);

            vm.Primitive(file, "close_(_)", Close);
            vm.Primitive(file, "descriptor", Descriptor);
            vm.Primitive(file, "readBytes_(_,_)", ReadBytes);
            vm.Primitive(file, "size_(_)", Size);
        }
Ejemplo n.º 12
0
        static void Main(string[] args)
        {
            Program program = new Program();    // 隐式转换 Program -> MyClass
            MyClass myClass = program;

            MyClass my  = new MyClass();        // 隐式转换 MyClass -> Program
            Program pro = my;

            Program  pro2 = new Program();      // 显示转换 Program -> objClass
            ObjClass obj  = (ObjClass)pro2;

            ObjClass obj2 = new ObjClass();     // 显示转换 objClass -> Program
            Program  pro3 = (Program)obj2;
        }
Ejemplo n.º 13
0
        } // GetLockedNodeCountForNodeType()

        public void GetNodeCounts( out Dictionary<Int32, Int32> NodeCountsForNodeType, out Dictionary<Int32, Int32> NodeCountsForObjectClass )
        {
            NodeCountsForNodeType = new Dictionary<Int32, Int32>();
            NodeCountsForObjectClass = new Dictionary<Int32, Int32>();

            foreach( CswNbtMetaDataObjectClass ObjClass in _CswNbtResources.MetaData.getObjectClasses() )
            {
                NodeCountsForObjectClass[ObjClass.ObjectClassId] = ObjClass.NodeCount;

                foreach( CswNbtMetaDataNodeType NodeType in ObjClass.getNodeTypes() )
                {
                    NodeCountsForNodeType[NodeType.NodeTypeId] = NodeType.NodeCount;
                }
            }
        } // _getNodeCounts()
        public override void update()
        {

            foreach( CswNbtMetaDataObjectClass ObjClass in _CswNbtSchemaModTrnsctn.MetaData.getObjectClasses() )
            {
                CswNbtMetaDataObjectClassProp LegacyIdOCP = ObjClass.getObjectClassProp( CswNbtObjClass.PropertyName.LegacyId );
                _CswNbtSchemaModTrnsctn.MetaData.UpdateObjectClassProp( LegacyIdOCP, CswEnumNbtObjectClassPropAttributes.servermanaged, true );

                foreach( CswNbtMetaDataNodeTypeProp LegacyIdNTP in LegacyIdOCP.getNodeTypeProps() )
                {
                    LegacyIdNTP.removeFromAllLayouts();
                }
            }

        } // update()
Ejemplo n.º 15
0
        // Verifies that [superclass] is a valid object to inherit from. That means it
        // must be a class and cannot be the class of any built-in type.
        //
        // If successful, returns null. Otherwise, returns a string for the runtime
        // error message.
        private static Obj ValidateSuperclass(Obj name, Obj superclassContainer)
        {
            // Make sure the superclass is a class.
            ObjClass superClass = superclassContainer as ObjClass;

            if (superClass != null)
            {
                // Make sure it doesn't inherit from a sealed built-in type. Primitive methods
                // on these classes assume the instance is one of the other Obj___ types and
                // will fail horribly if it's actually an ObjInstance.
                return(superClass.IsSealed ? Obj.MakeString(string.Format("Class '{0}' cannot inherit from built-in class '{1}'.", name as ObjString, (superClass.Name))) : null);
            }

            return(Obj.MakeString(string.Format("Class '{0}' cannot inherit from a non-class object.", name)));
        }
        private void _getViewProps(CswNbtView TempView, CswNbtViewEditorData Return)
        {
            foreach (CswNbtMetaDataNodeType NodeType in _CswNbtResources.MetaData.getNodeTypes()
                     .Where(nt => _CswNbtResources.Permit.canNodeType(CswEnumNbtNodeTypePermission.View, nt)))
            {
                CswNbtViewRelationship Relationship = TempView.AddViewRelationship(NodeType, true);
                //CswNbtViewNode foundNode = CurrentView.FindViewNodeByArbitraryId( Relationship.ArbitraryId );
                Return.Step2.Relationships.Add(Relationship);
                _addNameTemplateProps(TempView, Relationship, NodeType);
            }

            foreach (CswNbtMetaDataObjectClass ObjClass in _CswNbtResources.MetaData.getObjectClasses()
                     .Where(oc => false == oc.IsDesign() || _CswNbtResources.Permit.can(CswEnumNbtActionName.Design))                                                                      // case 31533
                     .OrderBy(ObjClass => ObjClass.ObjectClass.Value))
            {
                CswNbtViewRelationship Relationship = TempView.AddViewRelationship(ObjClass, true);
                //CswNbtViewNode foundNode = CurrentView.FindViewNodeByArbitraryId( Relationship.ArbitraryId );
                Return.Step2.Relationships.Add(Relationship);
                foreach (CswNbtMetaDataNodeType NodeType in ObjClass.getNodeTypes()
                         .Where(nt => _CswNbtResources.Permit.canNodeType(CswEnumNbtNodeTypePermission.View, nt)))
                {
                    _addNameTemplateProps(TempView, Relationship, NodeType);
                }
            }

            foreach (CswNbtMetaDataPropertySet PropSet in _CswNbtResources.MetaData.getPropertySets()
                     .OrderBy(PropSet => PropSet.Name))
            {
                CswNbtViewRelationship Relationship = TempView.AddViewRelationship(PropSet, true);
                //CswNbtViewNode foundNode = CurrentView.FindViewNodeByArbitraryId( Relationship.ArbitraryId );
                Return.Step2.Relationships.Add(Relationship);
                foreach (CswNbtMetaDataObjectClass ObjClass in PropSet.getObjectClasses()
                         .Where(oc => false == oc.IsDesign() || _CswNbtResources.Permit.can(CswEnumNbtActionName.Design)))                                                     // case 31533
                {
                    foreach (CswNbtMetaDataNodeType NodeType in ObjClass.getNodeTypes()
                             .Where(nt => _CswNbtResources.Permit.canNodeType(CswEnumNbtNodeTypePermission.View, nt)))
                    {
                        _addNameTemplateProps(TempView, Relationship, NodeType);
                    }
                }
            }
        }
Ejemplo n.º 17
0
        public static void LoadLibrary <T>(WrenVM vm)
            where T : IEnumerator
        {
            vm.Interpret("", "", WrenScriptLibSource);

            ObjClass scriptClass    = (ObjClass)vm.FindVariable("Script");
            ObjClass scriptRefClass = (ObjClass)vm.FindVariable("ScriptRef");

            List <string> underscores       = new List <string>();
            List <int>    registeredArities = new List <int>();

            foreach (var type in Assembly.GetCallingAssembly().GetTypes())
            {
                if (typeof(T).IsAssignableFrom(type))
                {
                    var attrs = type.GetCustomAttributes(true);
                    foreach (var attr in attrs)
                    {
                        var scriptName = attr as WrenNameAttribute;
                        if (scriptName != null)
                        {
                            registeredArities.Clear();
                            foreach (var ctor in type.GetConstructors())
                            {
                                bool ignore = false;
                                foreach (var ctorAttr in ctor.GetCustomAttributes(true))
                                {
                                    if (ctorAttr is WrenIgnoreAttribute)
                                    {
                                        ignore = true;
                                    }
                                }

                                if (!ignore)
                                {
                                    var constructor = ctor;                                     // capture a local cuz we're in a closure
                                    var parameters  = constructor.GetParameters();

                                    if (registeredArities.Contains(parameters.Length))
                                    {
                                        throw new Exception("Wren doesn't understand typed signatures so wren constructable classes shouldn't contain constructors with the same number of signatures");
                                    }

                                    registeredArities.Add(parameters.Length);

                                    underscores.Clear();
                                    foreach (var parameter in parameters)
                                    {
                                        underscores.Add("_");
                                    }

                                    var signature = scriptName.name + "(" + string.Join(",", underscores) + ")";
                                    vm.Primitive(scriptRefClass.ClassObj, signature, (primVM, args, stackStart) =>
                                    {
                                        try
                                        {
                                            object[] constructorArgs = new object[parameters.Length];
                                            for (int i = 0; i < parameters.Length; i++)
                                            {
                                                // Convert.ChangeType is mostly because numbers in wren are always doubles, but it might catch other cool stuff
                                                var arg            = args[stackStart + i + 1].Unbox();
                                                constructorArgs[i] = arg is IConvertible ? Convert.ChangeType(arg, parameters[i].ParameterType) : arg;
                                            }

                                            args[stackStart] = new ObjForeign()
                                            {
                                                foreign = constructor.Invoke(constructorArgs)
                                            };
                                            return(true);
                                        }
                                        catch (Exception e)
                                        {
                                            primVM.Fiber.Error = Obj.MakeString("Couldn't construct " + constructor.Name + ": " + e.Message);
                                            return(false);
                                        }
                                    });

                                    vm.Primitive(scriptClass.ClassObj, signature, (primVM, args, stackStart, success) =>
                                    {
                                        try
                                        {
                                            object[] constructorArgs = new object[parameters.Length];
                                            for (int i = 0; i < parameters.Length; i++)
                                            {
                                                var arg            = args[stackStart + i + 1].Unbox();
                                                constructorArgs[i] = arg is IConvertible ? Convert.ChangeType(arg, parameters[i].ParameterType) : arg;
                                            }

                                            var script = constructor.Invoke(constructorArgs);

                                            success.value = true;
                                            return(script as IEnumerator);
                                        }
                                        catch (Exception e)
                                        {
                                            primVM.Fiber.Error = Obj.MakeString("Couldn't construct " + constructor.Name + ": " + e.Message);
                                            success.value      = false;
                                            return(Noop());
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 18
0
        // The main bytecode interpreter loop. This is where the magic happens. It is
        // also, as you can imagine, highly performance critical. Returns `true` if the
        // fiber completed without error.
        private bool RunInterpreter()
        {
            /* Load Frame */
            CallFrame frame      = Fiber.Frames[Fiber.NumFrames - 1];
            int       ip         = frame.Ip;
            int       stackStart = frame.StackStart;

            Obj[] stack = Fiber.Stack;

            ObjFn fn = frame.Fn as ObjFn ?? ((ObjClosure)frame.Fn).Function;

            byte[] bytecode = fn.Bytecode;

            while (true)
            {
                Instruction instruction = (Instruction)bytecode[ip++];
                int         index;
                switch (instruction)
                {
                case Instruction.LOAD_LOCAL_0:
                case Instruction.LOAD_LOCAL_1:
                case Instruction.LOAD_LOCAL_2:
                case Instruction.LOAD_LOCAL_3:
                case Instruction.LOAD_LOCAL_4:
                case Instruction.LOAD_LOCAL_5:
                case Instruction.LOAD_LOCAL_6:
                case Instruction.LOAD_LOCAL_7:
                case Instruction.LOAD_LOCAL_8:
                {
                    index = stackStart + instruction - Instruction.LOAD_LOCAL_0;
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = stack[index];
                    break;
                }

                case Instruction.LOAD_LOCAL:
                {
                    index = stackStart + bytecode[ip++];
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = stack[index];
                    break;
                }

                case Instruction.LOAD_FIELD_THIS:
                {
                    byte        field    = bytecode[ip++];
                    ObjInstance instance = (ObjInstance)stack[stackStart];
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = instance.Fields[field];
                    break;
                }

                case Instruction.POP:
                {
                    Fiber.StackTop--;
                    break;
                }

                case Instruction.DUP:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop] = stack[Fiber.StackTop - 1];
                    Fiber.StackTop++;
                    break;
                }

                case Instruction.NULL:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = Obj.Null;
                    break;
                }

                case Instruction.FALSE:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = Obj.False;
                    break;
                }

                case Instruction.TRUE:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = Obj.True;
                    break;
                }

                case Instruction.CALL_0:
                case Instruction.CALL_1:
                case Instruction.CALL_2:
                case Instruction.CALL_3:
                case Instruction.CALL_4:
                case Instruction.CALL_5:
                case Instruction.CALL_6:
                case Instruction.CALL_7:
                case Instruction.CALL_8:
                case Instruction.CALL_9:
                case Instruction.CALL_10:
                case Instruction.CALL_11:
                case Instruction.CALL_12:
                case Instruction.CALL_13:
                case Instruction.CALL_14:
                case Instruction.CALL_15:
                case Instruction.CALL_16:
                // Handle Super calls
                case Instruction.SUPER_0:
                case Instruction.SUPER_1:
                case Instruction.SUPER_2:
                case Instruction.SUPER_3:
                case Instruction.SUPER_4:
                case Instruction.SUPER_5:
                case Instruction.SUPER_6:
                case Instruction.SUPER_7:
                case Instruction.SUPER_8:
                case Instruction.SUPER_9:
                case Instruction.SUPER_10:
                case Instruction.SUPER_11:
                case Instruction.SUPER_12:
                case Instruction.SUPER_13:
                case Instruction.SUPER_14:
                case Instruction.SUPER_15:
                case Instruction.SUPER_16:
                {
                    int numArgs = instruction - (instruction >= Instruction.SUPER_0 ? Instruction.SUPER_0 : Instruction.CALL_0) + 1;
                    int symbol  = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += 2;

                    // The receiver is the first argument.
                    int      argStart = Fiber.StackTop - numArgs;
                    Obj      receiver = stack[argStart];
                    ObjClass classObj;

                    if (instruction < Instruction.SUPER_0)
                    {
                        if (receiver.Type == ObjType.Obj)
                        {
                            classObj = receiver.ClassObj;
                        }
                        else if (receiver.Type == ObjType.Num)
                        {
                            classObj = NumClass;
                        }
                        else if (receiver == Obj.True || receiver == Obj.False)
                        {
                            classObj = BoolClass;
                        }
                        else
                        {
                            classObj = NullClass;
                        }
                    }
                    else
                    {
                        // The superclass is stored in a constant.
                        classObj = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]] as ObjClass;
                        ip      += 2;
                    }

                    // If the class's method table doesn't include the symbol, bail.
                    Method method = symbol < classObj.Methods.Length ? classObj.Methods[symbol] : null;

                    if (method == null)
                    {
                        /* Method not found */
                        frame.Ip = ip;
                        MethodNotFound(this, classObj, symbol);
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }

                    if (method.MType == MethodType.Primitive)
                    {
                        // After calling this, the result will be in the first arg slot.
                        if (method.Primitive(this, stack, argStart))
                        {
                            Fiber.StackTop = argStart + 1;
                        }
                        else
                        {
                            frame.Ip = ip;

                            if (Fiber.Error != null && Fiber.Error != Obj.Null)
                            {
                                if (!HandleRuntimeError())
                                {
                                    return(false);
                                }
                            }
                            else
                            {
                                // If we don't have a fiber to switch to, stop interpreting.
                                if (stack[argStart] == Obj.Null)
                                {
                                    return(true);
                                }
                                Fiber = stack[argStart] as ObjFiber;
                                if (Fiber == null)
                                {
                                    return(false);
                                }
                            }

                            /* Load Frame */
                            frame      = Fiber.Frames[Fiber.NumFrames - 1];
                            ip         = frame.Ip;
                            stackStart = frame.StackStart;
                            stack      = Fiber.Stack;
                            fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                            bytecode   = fn.Bytecode;
                        }
                        break;
                    }

                    frame.Ip = ip;

                    if (method.MType == MethodType.Block)
                    {
                        receiver = method.Obj;
                    }
                    else if (!CheckArity(stack, numArgs, argStart))
                    {
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }

                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }

                    Fiber.Frames.Add(frame = new CallFrame {
                            Fn = receiver, StackStart = argStart, Ip = 0
                        });
                    Fiber.NumFrames++;
                    /* Load Frame */
                    ip         = 0;
                    stackStart = argStart;
                    fn         = (receiver as ObjFn) ?? (receiver as ObjClosure).Function;
                    bytecode   = fn.Bytecode;
                    break;
                }

                case Instruction.STORE_LOCAL:
                {
                    index        = stackStart + bytecode[ip++];
                    stack[index] = stack[Fiber.StackTop - 1];
                    break;
                }

                case Instruction.CONSTANT:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]];
                    ip += 2;
                    break;
                }

                case Instruction.LOAD_UPVALUE:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = ((ObjClosure)frame.Fn).Upvalues[bytecode[ip++]].Container;
                    break;
                }

                case Instruction.STORE_UPVALUE:
                {
                    ObjUpvalue[] upvalues = ((ObjClosure)frame.Fn).Upvalues;
                    upvalues[bytecode[ip++]].Container = stack[Fiber.StackTop - 1];
                    break;
                }

                case Instruction.LOAD_MODULE_VAR:
                {
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = fn.Module.Variables[(bytecode[ip] << 8) + bytecode[ip + 1]].Container;
                    ip += 2;
                    break;
                }

                case Instruction.STORE_MODULE_VAR:
                {
                    fn.Module.Variables[(bytecode[ip] << 8) + bytecode[ip + 1]].Container = stack[Fiber.StackTop - 1];
                    ip += 2;
                    break;
                }

                case Instruction.STORE_FIELD_THIS:
                {
                    byte        field    = bytecode[ip++];
                    ObjInstance instance = (ObjInstance)stack[stackStart];
                    instance.Fields[field] = stack[Fiber.StackTop - 1];
                    break;
                }

                case Instruction.LOAD_FIELD:
                {
                    byte        field    = bytecode[ip++];
                    ObjInstance instance = (ObjInstance)stack[--Fiber.StackTop];
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = instance.Fields[field];
                    break;
                }

                case Instruction.STORE_FIELD:
                {
                    byte        field    = bytecode[ip++];
                    ObjInstance instance = (ObjInstance)stack[--Fiber.StackTop];
                    instance.Fields[field] = stack[Fiber.StackTop - 1];
                    break;
                }

                case Instruction.JUMP:
                {
                    int offset = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += offset + 2;
                    break;
                }

                case Instruction.LOOP:
                {
                    // Jump back to the top of the loop.
                    int offset = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += 2;
                    ip -= offset;
                    break;
                }

                case Instruction.JUMP_IF:
                {
                    int offset = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += 2;
                    Obj condition = stack[--Fiber.StackTop];

                    if (condition == Obj.False || condition == Obj.Null)
                    {
                        ip += offset;
                    }
                    break;
                }

                case Instruction.AND:
                case Instruction.OR:
                {
                    int offset = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += 2;
                    Obj condition = stack[Fiber.StackTop - 1];

                    if ((condition == Obj.Null || condition == Obj.False) ^ instruction == Instruction.OR)
                    {
                        ip += offset;
                    }
                    else
                    {
                        Fiber.StackTop--;
                    }
                    break;
                }

                case Instruction.CLOSE_UPVALUE:
                {
                    Fiber.CloseUpvalue();
                    Fiber.StackTop--;
                    break;
                }

                case Instruction.RETURN:
                {
                    Fiber.Frames.RemoveAt(--Fiber.NumFrames);
                    Obj result = stack[--Fiber.StackTop];
                    // Close any upvalues still in scope.
                    if (Fiber.StackTop > stackStart)
                    {
                        while (Fiber.OpenUpvalues != null && Fiber.OpenUpvalues.Index >= stackStart)
                        {
                            Fiber.CloseUpvalue();
                        }
                    }

                    // If the fiber is complete, end it.
                    if (Fiber.NumFrames == 0)
                    {
                        // If this is the main fiber, we're done.
                        if (Fiber.Caller == null)
                        {
                            return(true);
                        }

                        // We have a calling fiber to resume.
                        Fiber = Fiber.Caller;
                        stack = Fiber.Stack;
                        // Store the result in the resuming fiber.
                        stack[Fiber.StackTop - 1] = result;
                    }
                    else
                    {
                        // Discard the stack slots for the call frame (leaving one slot for the result).
                        Fiber.StackTop = stackStart + 1;

                        // Store the result of the block in the first slot, which is where the
                        // caller expects it.
                        stack[stackStart] = result;
                    }

                    /* Load Frame */
                    frame      = Fiber.Frames[Fiber.NumFrames - 1];
                    ip         = frame.Ip;
                    stackStart = frame.StackStart;
                    fn         = frame.Fn as ObjFn ?? (frame.Fn as ObjClosure).Function;
                    bytecode   = fn.Bytecode;
                    break;
                }

                case Instruction.CLOSURE:
                {
                    ObjFn prototype = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]] as ObjFn;
                    ip += 2;

                    // Create the closure and push it on the stack before creating upvalues
                    // so that it doesn't get collected.
                    ObjClosure closure = new ObjClosure(prototype);
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = closure;

                    // Capture upvalues.
                    for (int i = 0; i < prototype.NumUpvalues; i++)
                    {
                        byte isLocal = bytecode[ip++];
                        index = bytecode[ip++];
                        if (isLocal > 0)
                        {
                            // Make an new upvalue to close over the parent's local variable.
                            closure.Upvalues[i] = Fiber.CaptureUpvalue(stackStart + index);
                        }
                        else
                        {
                            // Use the same upvalue as the current call frame.
                            closure.Upvalues[i] = ((ObjClosure)frame.Fn).Upvalues[index];
                        }
                    }

                    break;
                }

                case Instruction.CLASS:
                {
                    Obj      name       = stack[Fiber.StackTop - 2];
                    ObjClass superclass = stack[Fiber.StackTop - 1] as ObjClass;

                    Obj error = ValidateSuperclass(name, stack[Fiber.StackTop - 1]);
                    if (error != null)
                    {
                        Fiber.Error = error;
                        frame.Ip    = ip;
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }

                    int numFields = bytecode[ip++];

                    Obj classObj = new ObjClass(superclass, numFields, name as ObjString);

                    // Don't pop the superclass and name off the stack until the subclass is
                    // done being created, to make sure it doesn't get collected.
                    Fiber.StackTop -= 2;

                    // Now that we know the total number of fields, make sure we don't overflow.
                    if (superclass.NumFields + numFields <= Compiler.MaxFields)
                    {
                        stack[Fiber.StackTop++] = classObj;
                        break;
                    }

                    // Overflow handling
                    frame.Ip    = ip;
                    Fiber.Error = Obj.MakeString(string.Format("Class '{0}' may not have more than 255 fields, including inherited ones.", name));
                    if (!HandleRuntimeError())
                    {
                        return(false);
                    }
                    /* Load Frame */
                    frame      = Fiber.Frames[Fiber.NumFrames - 1];
                    ip         = frame.Ip;
                    stackStart = frame.StackStart;
                    stack      = Fiber.Stack;
                    fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                    bytecode   = fn.Bytecode;
                    break;
                }

                case Instruction.METHOD_INSTANCE:
                case Instruction.METHOD_STATIC:
                {
                    int symbol = (bytecode[ip] << 8) + bytecode[ip + 1];
                    ip += 2;
                    ObjClass classObj = stack[Fiber.StackTop - 1] as ObjClass;
                    Obj      method   = stack[Fiber.StackTop - 2];
                    bool     isStatic = instruction == Instruction.METHOD_STATIC;
                    if (!BindMethod(isStatic, symbol, classObj, method))
                    {
                        frame.Ip    = ip;
                        Fiber.Error = Obj.MakeString("Error while binding method");
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }
                    Fiber.StackTop -= 2;
                    break;
                }

                case Instruction.LOAD_MODULE:
                {
                    Obj name = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]];
                    ip += 2;
                    Obj result = ImportModule(name);

                    // If it returned a string, it was an error message.
                    if ((result is ObjString))
                    {
                        frame.Ip    = ip;
                        Fiber.Error = result;
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }

                    // Make a slot that the module's fiber can use to store its result in.
                    // It ends up getting discarded, but CODE_RETURN expects to be able to
                    // place a value there.
                    if (Fiber.StackTop >= Fiber.Capacity)
                    {
                        stack = Fiber.IncreaseStack();
                    }
                    stack[Fiber.StackTop++] = Obj.Null;

                    // If it returned a fiber to execute the module body, switch to it.
                    if (result is ObjFiber)
                    {
                        // Return to this module when that one is done.
                        (result as ObjFiber).Caller = Fiber;

                        frame.Ip = ip;
                        Fiber    = (result as ObjFiber);
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                    }

                    break;
                }

                case Instruction.IMPORT_VARIABLE:
                {
                    Obj module = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]];
                    ip += 2;
                    Obj variable = fn.Constants[(bytecode[ip] << 8) + bytecode[ip + 1]];
                    ip += 2;
                    Obj result;
                    if (ImportVariable(module, variable, out result))
                    {
                        if (Fiber.StackTop >= Fiber.Capacity)
                        {
                            stack = Fiber.IncreaseStack();
                        }
                        stack[Fiber.StackTop++] = result;
                    }
                    else
                    {
                        frame.Ip    = ip;
                        Fiber.Error = result;
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                    }
                    break;
                }

                case Instruction.CONSTRUCT:
                {
                    int      stackPosition = Fiber.StackTop - 1 + (Instruction.CALL_0 - (Instruction)bytecode[ip]);
                    ObjClass v             = stack[stackPosition] as ObjClass;
                    if (v == null)
                    {
                        Fiber.Error = Obj.MakeString("'this' should be a class.");
                        if (!HandleRuntimeError())
                        {
                            return(false);
                        }
                        /* Load Frame */
                        frame      = Fiber.Frames[Fiber.NumFrames - 1];
                        ip         = frame.Ip;
                        stackStart = frame.StackStart;
                        stack      = Fiber.Stack;
                        fn         = (frame.Fn as ObjFn) ?? (frame.Fn as ObjClosure).Function;
                        bytecode   = fn.Bytecode;
                        break;
                    }
                    stack[stackPosition] = new ObjInstance(v);
                }
                break;

                case Instruction.FOREIGN_CLASS:
                    // Not yet implemented
                    break;

                case Instruction.FOREIGN_CONSTRUCT:
                    // Not yet implemented
                    break;

                case Instruction.END:
                    // A CODE_END should always be preceded by a CODE_RETURN. If we get here,
                    // the compiler generated wrong code.
                    return(false);
                }
            }

            // We should only exit this function from an explicit return from CODE_RETURN
            // or a runtime error.
        }
Ejemplo n.º 19
0
 // Creates a string containing an appropriate method not found error for a
 // method with [symbol] on [classObj].
 static void MethodNotFound(WrenVM vm, ObjClass classObj, int symbol)
 {
     vm.Fiber.Error = Obj.MakeString(string.Format("{0} does not implement '{1}'.", classObj.Name, vm.MethodNames[symbol]));
 }