public void Deserialize(Stream input) { BinaryReader mreader = new BinaryReader(input); int threadlen = mreader.ReadInt32(); for (int i = 0; i < threadlen; i++) { long pos = mreader.ReadInt64(); threads.Add(new VMThread() { executionState = pos }); } int objlen = mreader.ReadInt32(); for (int i = 0; i < objlen; i++) { double pos = mreader.ReadDouble(); int dlength = mreader.ReadInt32(); byte[] data = mreader.ReadBytes(dlength); VMObject obj = VMObject.Deserialize(data); obj.refValue = pos; assignment.internalobjects.Add(pos, obj); } }
public static VMObject Deserialize(byte[] data) { MemoryStream mstream = new MemoryStream(); mstream.Write(data, 0, data.Length); mstream.Position = 0; BinaryReader mreader = new BinaryReader(mstream); double typeid = mreader.ReadDouble(); //TODO: Decode the function variables int len = mreader.ReadInt32(); Dictionary <int, FunctionDeclaration> tempdecl = new Dictionary <int, FunctionDeclaration>(); for (int i = 0; i < len; i++) { FunctionDeclaration mdec = new FunctionDeclaration(); int key = mreader.ReadInt32(); int serlen = mreader.ReadInt32(); byte[] serdata = mreader.ReadBytes(serlen); if (serdata[0] == 0) { //Native method descriptor. TODO: Populate method info } else { //XVAR method descriptor byte[] xvardescriptor = new byte[serdata.Length - 1]; Buffer.BlockCopy(serdata, 1, xvardescriptor, 9, xvardescriptor.Length); mdec.function = xvardescriptor; } tempdecl.Add(key, mdec); } //NExt:: byte[] finaldata = new byte[mstream.Length - mstream.Position]; mstream.Read(finaldata, 0, finaldata.Length); VMObject retval = (VMObject)types[typeid].GetConstructor(new Type[] { typeof(byte[]) }).Invoke(new object[] { finaldata }); retval.functions = tempdecl; MethodInfo[] nativemethods = retval.GetType().GetMethods(); foreach (KeyValuePair <int, FunctionDeclaration> e in retval.functions) { if (e.Value.function == null) { //Hmm. Must be a somewhat 'inquisitive' native. e.Value.nativeMethod = nativemethods[e.Key]; } } return(retval); }
public object execXVARScript(BinaryReader source, ImportedObject[] imports) { //Create an XVARFunctionContainer int headercount = source.ReadInt32(); #region Generic import logic //Import imports from source machine foreach (ImportedObject e in imports) { internalobjects.Add(e.VObject.refValue, e.VObject); } //Import the global variables for (int i = 0; i < headercount; i++) { //Read in the reference value ON THE double (yes, pun intended :) double refval = source.ReadDouble(); if (source.ReadBoolean()) { int len = source.ReadInt32(); byte[] data = source.ReadBytes(len); VMObject obj = VMObject.Deserialize(data); obj.refValue = refval; internalobjects.Add(refval, obj); } else { internalobjects.Add(refval, null); } } //Read in the length of the INIT function long initlen = source.ReadInt64(); byte[] mainmethod = source.ReadBytes((int)initlen); XVARMethod method = new XVARMethod(mainmethod, this); //TODO: Invoke method with arguments return(method.Invoke(new VMObject[0])); #endregion }
public object execXVARScript(BinaryReader source, ImportedObject[] imports) { //Create an XVARFunctionContainer int headercount = source.ReadInt32(); #region Generic import logic //Import imports from source machine foreach (ImportedObject e in imports) { internalobjects.Add(e.VObject.refValue, e.VObject); } //Import the global variables for (int i = 0; i < headercount; i++) { //Read in the reference value ON THE double (yes, pun intended :) double refval = source.ReadDouble(); if (source.ReadBoolean()) { int len = source.ReadInt32(); byte[] data = source.ReadBytes(len); VMObject obj = VMObject.Deserialize(data); obj.refValue = refval; internalobjects.Add(refval, obj); } else { internalobjects.Add(refval, null); } } long beginningoffile = source.BaseStream.Position; //Read in the length of the INIT function long initlen = source.ReadInt64(); byte[] mainmethod = source.ReadBytes((int)initlen); XVARMethod method = new XVARMethod(source.BaseStream, this); //TODO: Read in all of the functions (with offsets) while (true) { try { //Read in function length, and download function int funclen = source.ReadInt32(); //TODO: Correct this. There should be a better way to load functions (without loading them all into RAM first. Maybe as variables somehow???) byte[] functiondata = source.ReadBytes(funclen); MemoryStream mstream = new MemoryStream(functiondata); BinaryReader mreader = new BinaryReader(mstream); //Read in the return type (not really used for anything at THIS point) mreader.ReadDouble(); //Read in associated object VMObject assocObj = internalobjects[mreader.ReadDouble()]; assocObj.functions.Add(mreader.ReadInt32(), new FunctionDeclaration() { function = functiondata }); mstream.Dispose(); } catch (EndOfStreamException) { break; } } //Invoke the MAIN method source.BaseStream.Position = beginningoffile; return(method.Invoke(new VMObject[0])); #endregion }
public void compileXVARScript(StreamReader source, ImportedObject[] imports, BinaryWriter output) { Dictionary <string, VMObject> objects = new Dictionary <string, VMObject>(); double objPos = 0; #region Import logic output.Write(imports.ToArray().Length); foreach (ImportedObject e in imports) { objects.Add(e.Name, e.VObject); if (e.VObject.refValue >= objPos) { //Write the reference value as a double! output.Write(e.VObject.refValue); //Whether or not to literally interpolate the value output.Write(e.VObject.storeAsLiteral); //TODO here //Somehow convert the native functions relating to the object into virtual XVAR function //definitions MethodInfo[] methods = e.VObject.GetType().GetMethods(); try { int methodindex = 0; foreach (MethodInfo et in methods) { e.VObject.functions.Add(methodindex, new FunctionDeclaration() { nativeMethod = et }); e.VObject.functionIdentifiers.Add(et.Name, methodindex); methodindex += 1; } } catch (Exception) { //Must have already been added } //END TODO here if (e.VObject.storeAsLiteral) { byte[] data = e.VObject.Serialize(); output.Write(data.Length); output.Write(data); } objPos = e.VObject.refValue + 1; } } #endregion //Opcode 4 = Internal function offset declaration (long) #region Compilation logic long lastfunctionoffset = 0; bool hascalled = false; long spos = output.BaseStream.Position; int funcID = 0; output.Write((long)0); long zpos = output.BaseStream.Position; string currentFunction = ""; FunctionDeclaration mdec = new FunctionDeclaration(); Dictionary <string, long> lostandfound = new Dictionary <string, long>(); VMObject parentObject = null; while (!source.EndOfStream) { string instruction = source.ReadLine(); string[] parts = intellisplit(instruction); if (parts[0] == "function") { mdec = new FunctionDeclaration(); output.BaseStream.Position = lastfunctionoffset; //Length of function output.Write((int)0); currentFunction = parts[3]; //Return type foreach (KeyValuePair <double, Type> e in VMObject.types) { if (e.Value.Name == parts[1]) { output.Write(e.Key); break; } } //Associate function with object VMObject obj = objects[parts[2]]; parentObject = obj; output.Write(obj.refValue); int ival = obj.functions.Count + 1; funcID = ival; obj.functionIdentifiers.Add(parts[3], ival); //Write out the index of the function output.Write(ival); } if (parts[0] == "ndfunction") { long yval = output.BaseStream.Position; int tval = (int)(output.BaseStream.Position - lastfunctionoffset); output.BaseStream.Position = lastfunctionoffset; //Write function length output.Write(tval); //Data's already been written. Seek to beginning of stream! output.BaseStream.Position = yval; //Read the function back in output.BaseStream.Position = lastfunctionoffset; //Read function byte array byte[] mray = new byte[tval]; output.BaseStream.Read(mray, 0, mray.Length); mdec.function = mray; long previous = lastfunctionoffset; parentObject.functions.Add(funcID, mdec); lastfunctionoffset = output.BaseStream.Position; if (lostandfound.Keys.Contains(currentFunction)) { output.BaseStream.Position = lostandfound[currentFunction]; output.Write(previous); output.BaseStream.Position = lastfunctionoffset; } } if (parts[0] == "unalloc") { //Opcode 3 try { output.Write((byte)3); output.Write(objects[parts[1]].refValue); objects.Remove(parts[1]); } catch (KeyNotFoundException) { throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared."); } } if (parts[0] == "stralloc") { //Opcode 2 output.Write((byte)2); //Store the string to a variable parts[1] = parts[1].Replace("\"", ""); output.Write(parts[1]); if (objects.Keys.Contains(parts[2])) { objects[parts[2]] = new VMString(parts[1]) { refValue = objPos }; } else { objects.Add(parts[2], new VMString(parts[1]) { refValue = objPos }); } output.Write(objPos); objPos += 1; } if (parts[0] == "ndinit") { if (!hascalled) { long cpos = output.BaseStream.Position; output.BaseStream.Position = spos; output.Write(cpos - zpos); output.BaseStream.Position = cpos; hascalled = true; lastfunctionoffset = cpos; } else { throw new ArgumentException("endinit may only be called once per session! What were you thinking?!?!?"); } } if (parts[0] == "call") { //Write out opcode (as byte) VMObject currentObj = objects[parts[1]]; if (!currentObj.functionIdentifiers.ContainsKey(parts[2])) { output.Write((byte)4); long ntpos = output.BaseStream.Position; //Function offset to be determined output.Write((long)-1); lostandfound.Add(parts[2], ntpos); } else { output.Write((byte)0); try { //Write out index of reference object (as double) output.Write(currentObj.refValue); try { FunctionDeclaration function = currentObj.functions[currentObj.functionIdentifiers[parts[2]]]; //Write out index of function (as int32) output.Write(currentObj.functionIdentifiers[parts[2]]); //Write out length of parameters (as int32) string[] args; try { args = parts[3].Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries); if (args[0] == "null") { args = new string[0]; } } catch (Exception) { args = new string[0]; } output.Write(args.Length); foreach (string et in args) { //Write out each reference as a double output.Write(objects[et].refValue); } if (parts.Length == 5) { //Whether or not the output should be assigned to a variable output.Write(true); //The variable to assign it to if (objects.ContainsKey(parts[4])) { output.Write(objects[parts[4]].refValue); } else { VMObject tobj = (VMObject)function.returnType.GetConstructor(new Type[0]).Invoke(null); tobj.refValue = objPos; //Populate the object's methods objects.Add(parts[4], tobj); output.Write(objPos); objPos += 1; } } else { output.Write(false); } } catch (AccessViolationException) { } } catch (KeyNotFoundException) { throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared."); } } } } #endregion }
public GenericObj(VMObject obj, string iname) { internObj = obj; Name = iname; }
public void compileXVARScript(StreamReader source, ImportedObject[] imports, BinaryWriter output) { Dictionary <string, VMObject> objects = new Dictionary <string, VMObject>(); double objPos = 0; #region Import logic output.Write(imports.ToArray().Length); foreach (ImportedObject e in imports) { objects.Add(e.Name, e.VObject); if (e.VObject.refValue >= objPos) { //Write the reference value as a double! output.Write(e.VObject.refValue); //Whether or not to literally interpolate the value output.Write(e.VObject.storeAsLiteral); //TODO here //Somehow convert the native functions relating to the object into virtual XVAR function //definitions MethodInfo[] methods = e.VObject.GetType().GetMethods(); try { int methodindex = 0; foreach (MethodInfo et in methods) { e.VObject.functions.Add(methodindex, new FunctionDeclaration() { nativeMethod = et }); e.VObject.functionIdentifiers.Add(et.Name, methodindex); methodindex += 1; } } catch (Exception) { //Must have already been added } //END TODO here if (e.VObject.storeAsLiteral) { byte[] data = e.VObject.Serialize(); output.Write(data.Length); output.Write(data); } objPos = e.VObject.refValue + 1; } } #endregion #region Compilation logic bool hascalled = false; long spos = output.BaseStream.Position; output.Write((long)0); while (!source.EndOfStream) { string instruction = source.ReadLine(); string[] parts = intellisplit(instruction); if (parts[0] == "unalloc") { //Opcode 3 try { output.Write((byte)3); output.Write(objects[parts[1]].refValue); objects.Remove(parts[1]); } catch (KeyNotFoundException) { throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared."); } } if (parts[0] == "allocstr") { //Opcode 2 output.Write((byte)2); //Store the string to a variable parts[1] = parts[1].Replace("\"", ""); output.Write(parts[1]); if (objects.Keys.Contains(parts[2])) { objects[parts[2]] = new VMString(parts[1]) { refValue = objPos }; } else { objects.Add(parts[2], new VMString(parts[1]) { refValue = objPos }); } output.Write(objPos); objPos += 1; } if (parts[0] == "ndinit") { if (!hascalled) { long cpos = output.BaseStream.Position; output.BaseStream.Position = spos; output.Write(cpos); output.BaseStream.Position = cpos; hascalled = true; } else { throw new ArgumentException("endinit may only be called once per session! What were you thinking?!?!?"); } } if (parts[0] == "call") { //Write out opcode (as byte) output.Write((byte)0); try { VMObject currentObj = objects[parts[1]]; //Write out index of reference object (as double) output.Write(currentObj.refValue); try { FunctionDeclaration function = currentObj.functions[currentObj.functionIdentifiers[parts[2]]]; //Write out index of function (as int32) output.Write(currentObj.functionIdentifiers[parts[2]]); //Write out length of parameters (as int32) string[] args; try { args = parts[3].Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries); if (args[0] == "null") { args = new string[0]; } } catch (Exception) { args = new string[0]; } output.Write(args.Length); foreach (string et in args) { //Write out each reference as a double output.Write(objects[et].refValue); } if (parts.Length == 5) { //Whether or not the output should be assigned to a variable output.Write(true); //The variable to assign it to if (objects.ContainsKey(parts[4])) { output.Write(objects[parts[4]].refValue); } else { VMObject tobj = (VMObject)function.returnType.GetConstructor(new Type[0]).Invoke(null); tobj.refValue = objPos; //Populate the object's methods objects.Add(parts[4], tobj); output.Write(objPos); objPos += 1; } } else { output.Write(false); } } catch (Exception) { throw new MethodAccessException("The function " + parts[2] + " does not exist."); } } catch (KeyNotFoundException) { throw new NullReferenceException("Invalid reference. Variable " + parts[1] + " has not been declared."); } } } #endregion }
public VMObject Invoke(VMObject[] args) { //Parse the code in the script and return the resultant value BinaryReader mreader = new BinaryReader(internstream); while(true) { try { byte opcode = mreader.ReadByte(); if (opcode == 3) { vmInstance.internalobjects.Remove(mreader.ReadDouble()); } if (opcode == 2) { string txt = mreader.ReadString(); VMString mstr = new VMString(txt); mstr.refValue = mreader.ReadDouble(); if (vmInstance.internalobjects.Keys.Contains(mstr.refValue)) { vmInstance.internalobjects[mstr.refValue] = mstr; } else { vmInstance.internalobjects.Add(mstr.refValue, mstr); } } if (opcode == 1) { //CALL and RETURN statement double objIndex = mreader.ReadDouble(); VMObject obj = vmInstance.internalobjects[objIndex]; //Read in index of function (as a 32 bit integer) int functionIndex = mreader.ReadInt32(); FunctionDeclaration function = obj.functions[functionIndex]; //Read in array of parameters int paramlen = mreader.ReadInt32(); List<object> parameters = new List<object>(); for (int i = 0; i < paramlen; i++) { parameters.Add(vmInstance.internalobjects[mreader.ReadDouble()]); } return (VMObject)function.Invoke(parameters.ToArray(), obj); } if (opcode == 0) { //CALL statement double objIndex = mreader.ReadDouble(); VMObject obj = vmInstance.internalobjects[objIndex]; //Read in index of function (as a 32 bit integer) int functionIndex = mreader.ReadInt32(); FunctionDeclaration function = obj.functions[functionIndex]; //Read in array of parameters int paramlen = mreader.ReadInt32(); List<object> parameters = new List<object>(); for (int i = 0; i < paramlen; i++) { parameters.Add(vmInstance.internalobjects[mreader.ReadDouble()]); } VMObject assignment = (VMObject)function.Invoke(parameters.ToArray(),obj); if (mreader.ReadBoolean()) { double assignmentVar = mreader.ReadDouble(); assignment.refValue = assignmentVar; if (vmInstance.internalobjects.Keys.Contains(assignmentVar)) { vmInstance.internalobjects[assignmentVar] = assignment; } else { vmInstance.internalobjects.Add(assignmentVar, assignment); } } } }catch(EndOfStreamException) { return null; } } }
public VMObject Invoke(VMObject[] args) { //Parse the code in the script and return the resultant value BinaryReader mreader = new BinaryReader(internstream); while (true) { try { byte opcode = mreader.ReadByte(); if (opcode == 3) { vmInstance.internalobjects.Remove(mreader.ReadDouble()); } if (opcode == 2) { string txt = mreader.ReadString(); VMString mstr = new VMString(txt); mstr.refValue = mreader.ReadDouble(); if (vmInstance.internalobjects.Keys.Contains(mstr.refValue)) { vmInstance.internalobjects[mstr.refValue] = mstr; } else { vmInstance.internalobjects.Add(mstr.refValue, mstr); } } if (opcode == 1) { //CALL and RETURN statement double objIndex = mreader.ReadDouble(); VMObject obj = vmInstance.internalobjects[objIndex]; //Read in index of function (as a 32 bit integer) int functionIndex = mreader.ReadInt32(); FunctionDeclaration function = obj.functions[functionIndex]; //Read in array of parameters int paramlen = mreader.ReadInt32(); List <object> parameters = new List <object>(); for (int i = 0; i < paramlen; i++) { parameters.Add(vmInstance.internalobjects[mreader.ReadDouble()]); } return((VMObject)function.Invoke(parameters.ToArray(), obj)); } if (opcode == 0) { //CALL statement double objIndex = mreader.ReadDouble(); VMObject obj = vmInstance.internalobjects[objIndex]; //Read in index of function (as a 32 bit integer) int functionIndex = mreader.ReadInt32(); FunctionDeclaration function = obj.functions[functionIndex]; //Read in array of parameters int paramlen = mreader.ReadInt32(); List <object> parameters = new List <object>(); for (int i = 0; i < paramlen; i++) { parameters.Add(vmInstance.internalobjects[mreader.ReadDouble()]); } VMObject assignment = (VMObject)function.Invoke(parameters.ToArray(), obj); if (mreader.ReadBoolean()) { double assignmentVar = mreader.ReadDouble(); assignment.refValue = assignmentVar; if (vmInstance.internalobjects.Keys.Contains(assignmentVar)) { vmInstance.internalobjects[assignmentVar] = assignment; } else { vmInstance.internalobjects.Add(assignmentVar, assignment); } } } }catch (EndOfStreamException) { return(null); } } }