/// <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; } }
public static void LoadLibrary(WrenVM vm) { vm.Interpret("timer", "timer", _timerSource); ObjClass timer = (ObjClass)vm.FindVariable("timer", "Timer"); vm.Primitive(timer.ClassObj, "startTimer_(_,_)", StartTimer); }
// 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 }
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_()"); }
public static void LoadLibrary(WrenVM vm) { vm.Interpret("", "", MetaLibSource); ObjClass meta = (ObjClass)vm.FindVariable("Meta"); vm.Primitive(meta.ClassObj, "eval(_)", Eval); }
// 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; }
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; } }
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 }); }
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); }
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; }
} // 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()
// 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); } } } }
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()); } }); } } } } } } }
// 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. }
// 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])); }