// call using serialised native arguments, return serialised native result internal bool NativeCall(string name, byte[] arguments, out byte[] result) { var kind = _catvars.GetKind(name); if (kind != EntryKinds.Code) { return(NativeFail("unknown or invalid name: " + name, out result)); } var expr = (_catvars.GetValue(name) as CodeValue).Value; TypedValue[] argvalues = new TypedValue[expr.NumArgs]; using (var pr = PersistReader.Create(arguments)) { for (var i = 0; i < expr.NumArgs; ++i) { try { argvalues[i] = pr.Read(expr.Lookup.Columns[i].DataType); // BUG: needs heading } catch { return(NativeFail("argument conversion error", out result)); } } } var argvalue = DataRow.CreateNonTuple(expr.Lookup, argvalues); TypedValue retvalue; try { retvalue = _evaluator.Exec(expr.Code, argvalue); } catch (ProgramException ex) { return(NativeFail(ex.ToString(), out result)); } using (var pw = PersistWriter.Create()) { pw.Write(retvalue); result = pw.ToArray(); } return(true); }
// Read a code stream and decode it void Decode(PersistReader preader) { while (preader.BaseStream.Position < preader.BaseStream.Length) { var opcode = preader.ReadOpcode(); var prefix = String.Format("|{0}{1,4}: {2,-9}", // nopad new String(' ', _indent * 4), preader.BaseStream.Position - 1, opcode); switch (opcode) { // Known literal, do not translate into value case Opcodes.LDVALUE: //TODO: recurse case Opcodes.LDAGG: var value = preader.ReadValue(); Logger.WriteLine(3, "{0}{1}", prefix, value); if (value.DataType is DataTypeCode) { Decode((value as CodeValue).Value.Code); } break; case Opcodes.LDSEG: //TODO: recurse var code = preader.ReadExpr(); Logger.WriteLine(3, "{0}{1}", prefix, code); Decode(code.Code); break; case Opcodes.LDCAT: case Opcodes.LDCATR: case Opcodes.LDCATV: case Opcodes.LDFIELD: case Opcodes.LDCOMP: case Opcodes.LDFIELDT: Logger.WriteLine(3, "{0}{1}", prefix, preader.ReadString()); break; case Opcodes.LDACC: Logger.WriteLine(3, "{0}{1} seed={2}", prefix, preader.ReadInteger(), preader.ReadValue()); break; // Call a function, fixed or variable arg count case Opcodes.CALL: case Opcodes.CALLV: case Opcodes.CALLVT: Logger.WriteLine(3, "{0}{1} ({2}, {3})", prefix, preader.ReadString(), preader.ReadByte(), preader.ReadByte()); break; case Opcodes.LDLOOKUP: case Opcodes.LDACCBLK: case Opcodes.EOS: Logger.WriteLine(3, "{0}", prefix); break; default: throw new NotImplementedException(opcode.ToString()); } } }
void Decode(ByteCode code) { if (code.Length > 0) { _indent++; Decode(PersistReader.Create(code.bytes)); _indent--; } }
static public Decoder Create(ByteCode code) { var dc = new Decoder { Code = code, _mstream = new MemoryStream(code.bytes) }; dc._preader = PersistReader.Create(new BinaryReader(dc._mstream)); return(dc); }
private static object Deserialize(FastStreamReader streamReader) { using (PersistReader reader = new PersistReader()) { bool enableTypeRemapping = Persist.EnableTypeRemapping; Persist.EnableTypeRemapping = false; bool requireAllPersistable = Persist.RequireAllPersistable; Persist.RequireAllPersistable = true; try { reader.Load(streamReader, null); } finally { Persist.EnableTypeRemapping = enableTypeRemapping; Persist.RequireAllPersistable = requireAllPersistable; } return((reader.Count > 0) ? reader[0] : null); } }