// Compile functions to find errors. Does not do a full build - compiles only this module and does // not check function arg/return types for references to other modules. public bool TestBuild( bool force, PcodeSystem.IEvaluationContext pcodeEnvironment, BuildFailedCallback failedCallback, CodeCenterRec throwAwayCodeCenter) { int ErrorLine; int ErrorModuleIndex; CompileErrors Error = Compiler.CompileWholeProgram( out ErrorLine, out ErrorModuleIndex, new string[] { this.Source }, new object[] { this }, throwAwayCodeCenter, // use throw-away linker to not pollute the real one with unchecked function calls new string[] { this.Name }); if ((Error != CompileErrors.eCompileNoError) // these errors are permitted for test-build because without full function signatures known there will be // arg-type inference ambiguities. && (Error != CompileErrors.eCompileMultiplyDeclaredFunction)) { failedCallback( this, new LiteralBuildErrorInfo(Compiler.GetCompileErrorString(Error), ErrorLine)); return(false); } return(true); }
private void Eval() { if (!mainWindow.MakeUpToDate()) { return; } int ErrorLineNumberCompilation; DataTypes ReturnType; PcodeRec FuncCode; Compiler.ASTExpression AST; CompileErrors CompileError = Compiler.CompileSpecialFunction( mainWindow.Document.CodeCenter, new FunctionParamRec[] { new FunctionParamRec("frames", DataTypes.eInteger), new FunctionParamRec("tables", DataTypes.eInteger), new FunctionParamRec("data", DataTypes.eArrayOfFloat), }, out ErrorLineNumberCompilation, out ReturnType, textBoxFormula.Text, false/*suppressCILEmission*/, out FuncCode, out AST); if (CompileError != CompileErrors.eCompileNoError) { textBoxFormula.Focus(); textBoxFormula.SetSelectionLine(ErrorLineNumberCompilation - 1); textBoxFormula.ScrollToSelection(); LiteralBuildErrorInfo errorInfo = new LiteralBuildErrorInfo(Compiler.GetCompileErrorString(CompileError), ErrorLineNumberCompilation); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } using (ParamStackRec ParamList = new ParamStackRec()) { int numFrames = waveTableObject.WaveTableData.NumFrames; int numTables = waveTableObject.WaveTableData.NumTables; float[] vector = new float[numFrames * numTables]; ArrayHandleFloat dataHandle = new ArrayHandleFloat(vector); int initialCapacity = 1/*frames*/ + 1/*tables*/ + 1/*data*/ + 1/*retaddr*/; ParamList.EmptyParamStackEnsureCapacity(initialCapacity); ParamList.AddIntegerToStack(numFrames); ParamList.AddIntegerToStack(numTables); ParamList.AddArrayToStack(dataHandle); ParamList.AddIntegerToStack(0); /* return address placeholder */ for (int i = 0; i < numTables; i++) { WaveTableStorageRec.Table table = waveTableObject.WaveTableData.ListOfTables[i]; for (int j = 0; j < numFrames; j++) { vector[i * numFrames + j] = table[j]; } } CodeCenterRec CodeCenter = mainWindow.Document.CodeCenter; EvalErrInfoRec ErrorInfo; EvalErrors EvaluationError = PcodeSystem.EvaluatePcodeThread.EvaluatePcode( ParamList, FuncCode, CodeCenter, out ErrorInfo, new PcodeExterns(mainWindow)); if (EvaluationError != EvalErrors.eEvalNoError) { PcodeEvaluationErrorInfo errorInfo = new PcodeEvaluationErrorInfo( EvaluationError, ErrorInfo, FuncCode, CodeCenter); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } Debug.Assert(ParamList.GetStackNumElements() == initialCapacity); // args - retaddr + return value #if DEBUG ParamList.Elements[2].AssertFloatArray(); #endif dataHandle = ParamList.Elements[2].reference.arrayHandleFloat; WaveTableStorageRec NewTable = new WaveTableStorageRec(numTables, numFrames, waveTableObject.WaveTableData.NumBits); float[] NewData = dataHandle.floats; if (NewData.Length != numTables * numFrames) { PcodeEvaluationErrorInfo errorInfo = new PcodeEvaluationErrorInfo( "<anonymous>", PcodeSystem.GetPcodeErrorMessage(EvalErrors.eEvalArrayWrongDimensions), 1); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } SampConv.QuantizeAndClampVector(NewData, NewTable.NumBits); for (int i = 0; i < numTables; i++) { WaveTableStorageRec.Table table = NewTable.ListOfTables[i]; for (int j = 0; j < numFrames; j++) { table[j] = NewData[i * numFrames + j]; } } undo.Push(waveTableObject.WaveTableData); redo.Clear(); waveTableObject.WaveTableData = NewTable; } }
/* compile a special function. a special function has no function header, but is */ /* simply some code to be executed. the parameters the code is expecting are provided */ /* in the FuncArray[] and NumParams. the first parameter is deepest beneath the */ /* top of stack. the TextData is NOT altered. if an error occurrs, *FunctionOut */ /* will NOT contain a valid object */ public static CompileErrors CompileSpecialFunction( CodeCenterRec CodeCenter, FunctionParamRec[] FuncArray, out int ErrorLineNumber, out DataTypes ReturnTypeOut, string TextData, bool suppressCILEmission, out PcodeRec FunctionOut, out ASTExpression ASTOut) { CompileErrors Error; ErrorLineNumber = -1; ASTOut = null; FunctionOut = null; ReturnTypeOut = DataTypes.eInvalidDataType; ScannerRec <KeywordsType> TheScanner = new ScannerRec <KeywordsType>(TextData, KeywordTable); SymbolTableRec TheSymbolTable = new SymbolTableRec(); // reconstitute function prototypes for (int i = 0; i < CodeCenter.RetainedFunctionSignatures.Length; i++) { SymbolRec functionSignature = ArgListTypesToSymbol( CodeCenter.RetainedFunctionSignatures[i].Key, CodeCenter.RetainedFunctionSignatures[i].Value.ArgsTypes, CodeCenter.RetainedFunctionSignatures[i].Value.ReturnType); bool f = TheSymbolTable.Add(functionSignature); Debug.Assert(f); // should never fail (due to duplicate) since CodeCenter.RetainedFunctionSignatures is unique-keyed } /* build parameters into symbol table */ int StackDepth = 0; int MaxStackDepth = 0; int ReturnAddressIndex = StackDepth; for (int i = 0; i < FuncArray.Length; i += 1) { SymbolRec TheParameter = new SymbolRec(FuncArray[i].ParameterName); TheParameter.SymbolBecomeVariable(FuncArray[i].ParameterType); /* allocate stack slot */ StackDepth++; MaxStackDepth = Math.Max(MaxStackDepth, StackDepth); TheParameter.SymbolVariableStackLocation = StackDepth; if (!TheSymbolTable.Add(TheParameter)) // our own code should never pass in a formal arg list with duplicates { Debug.Assert(false); throw new InvalidOperationException(); } } /* fence them off */ TheSymbolTable.IncrementSymbolTableLevel(); /* reserve spot for fake return address (so we have uniform calling convention everywhere) */ StackDepth++; MaxStackDepth = Math.Max(MaxStackDepth, StackDepth); if (StackDepth != FuncArray.Length + 1) { // stack depth error before evaluating function Debug.Assert(false); throw new InvalidOperationException(); } ASTExpressionList ListOfExpressions; Error = ParseExprList( out ListOfExpressions, new ParserContext( TheScanner, TheSymbolTable), out ErrorLineNumber); /* compile the thing */ if (Error != CompileErrors.eCompileNoError) { return(Error); } ASTExpression TheExpressionThang = new ASTExpression( ListOfExpressions, TheScanner.GetCurrentLineNumber()); /* make sure there is nothing after it */ TokenRec <KeywordsType> Token = TheScanner.GetNextToken(); if (Token.GetTokenType() != TokenTypes.eTokenEndOfInput) { ErrorLineNumber = TheScanner.GetCurrentLineNumber(); return(CompileErrors.eCompileInputBeyondEndOfFunction); } DataTypes ResultingType; Error = TheExpressionThang.TypeCheck(out ResultingType, out ErrorLineNumber); if (Error != CompileErrors.eCompileNoError) { return(Error); } OptimizeAST(ref TheExpressionThang); PcodeRec TheFunctionCode = new PcodeRec(); TheExpressionThang.PcodeGen( TheFunctionCode, ref StackDepth, ref MaxStackDepth); Debug.Assert(StackDepth <= MaxStackDepth); ReturnTypeOut = TheExpressionThang.ResultType; /* 2 extra words for retaddr, resultofexpr */ if (StackDepth != FuncArray.Length + 1 /*retaddr*/ + 1 /*result*/) { // stack depth error after evaluating function Debug.Assert(false); throw new InvalidOperationException(); } /* now put the return instruction */ int unused; TheFunctionCode.AddPcodeInstruction(Pcodes.epReturnFromSubroutine, out unused, TheScanner.GetCurrentLineNumber()); // special function returns without popping args -- so that args can be have in/out behavior TheFunctionCode.AddPcodeOperandInteger(0); StackDepth -= 1; /* pop retaddr */ Debug.Assert(StackDepth <= MaxStackDepth); if (StackDepth != 1 + FuncArray.Length) { // stack depth is wrong at end of function Debug.Assert(false); throw new InvalidOperationException(); } TheFunctionCode.MaxStackDepth = MaxStackDepth; /* optimize stupid things away */ TheFunctionCode.OptimizePcode(); if (CILObject.EnableCIL && !suppressCILEmission) { DataTypes[] argsTypes = new DataTypes[FuncArray.Length]; string[] argsNames = new string[FuncArray.Length]; for (int i = 0; i < argsTypes.Length; i++) { argsTypes[i] = FuncArray[i].ParameterType; argsNames[i] = FuncArray[i].ParameterName; } CILAssembly cilAssembly = new CILAssembly(); CILObject cilObject = new CILObject( CodeCenter.ManagedFunctionLinker, argsTypes, argsNames, TheExpressionThang.ResultType, TheExpressionThang, cilAssembly, true /*argsByRef*/); // args by ref true for special functions to permit multiple return values TheFunctionCode.cilObject = cilObject; cilAssembly.Finish(); } /* it worked, so return the dang thing */ FunctionOut = TheFunctionCode; ASTOut = TheExpressionThang; return(CompileErrors.eCompileNoError); }
// Compile multiple modules. (eliminates the need to do prototyping or function signature inference.) // CodeCenter is cleared, and if compilation succeeds, the functions are added to CodeCenter. public static CompileErrors CompileWholeProgram( out int ErrorLineNumber, out int ErrorModuleIndex, string[] TextDatas, object[] Signatures, CodeCenterRec CodeCenter, string[] Filenames) { Debug.Assert(TextDatas.Length == Signatures.Length); Debug.Assert(TextDatas.Length == Filenames.Length); ErrorLineNumber = -1; ErrorModuleIndex = -1; CodeCenter.FlushAllCompiledFunctions(); CodeCenter.RetainedFunctionSignatures = new KeyValuePair <string, FunctionSignature> [0]; // parse List <SymbolRec> SymbolTableEntriesForForm = new List <SymbolRec>(); List <ASTExpression> FunctionBodyRecords = new List <ASTExpression>(); List <int> ModuleIndices = new List <int>(); Dictionary <string, List <ParserContext.FunctionSymbolRefInfo> > FunctionRefSymbolList = new Dictionary <string, List <ParserContext.FunctionSymbolRefInfo> >(); List <int> InitialLineNumbersOfForm = new List <int>(); for (int module = 0; module < TextDatas.Length; module++) { string TextData = TextDatas[module]; ErrorModuleIndex = module; ScannerRec <KeywordsType> TheScanner = new ScannerRec <KeywordsType>(TextData, KeywordTable); SymbolTableRec TheSymbolTable = new SymbolTableRec(); /* loop until there are no more things to parse */ while (true) { TokenRec <KeywordsType> Token = TheScanner.GetNextToken(); int InitialLineNumberOfForm = TheScanner.GetCurrentLineNumber(); if (Token.GetTokenType() == TokenTypes.eTokenEndOfInput) { /* no more functions to parse, so stop */ break; } SymbolRec SymbolTableEntryForForm; ASTExpression FunctionBodyRecord; /* parse the function */ TheScanner.UngetToken(Token); CompileErrors Error = ParseForm( out SymbolTableEntryForForm, out FunctionBodyRecord, new ParserContext( TheScanner, TheSymbolTable, FunctionRefSymbolList), out ErrorLineNumber); if (Error != CompileErrors.eCompileNoError) { return(Error); } Debug.Assert(FunctionBodyRecord != null); ModuleIndices.Add(module); SymbolTableEntriesForForm.Add(SymbolTableEntryForForm); FunctionBodyRecords.Add(FunctionBodyRecord); InitialLineNumbersOfForm.Add(InitialLineNumberOfForm); } foreach (KeyValuePair <string, List <ParserContext.FunctionSymbolRefInfo> > name in FunctionRefSymbolList) { foreach (ParserContext.FunctionSymbolRefInfo funcRef in name.Value) { funcRef.module = module; } } } // push function type signatures into function call refs Dictionary <string, bool> functionNamesUsed = new Dictionary <string, bool>(); for (int i = 0; i < SymbolTableEntriesForForm.Count; i++) { ErrorModuleIndex = ModuleIndices[i]; SymbolRec FunctionDeclarationSymbol = SymbolTableEntriesForForm[i]; if (functionNamesUsed.ContainsKey(FunctionDeclarationSymbol.SymbolName)) { ErrorLineNumber = FunctionBodyRecords[i].LineNumber; return(CompileErrors.eCompileMultiplyDeclaredFunction); } functionNamesUsed.Add(FunctionDeclarationSymbol.SymbolName, false); List <ParserContext.FunctionSymbolRefInfo> symbols; if (FunctionRefSymbolList.TryGetValue(FunctionDeclarationSymbol.SymbolName, out symbols)) { foreach (ParserContext.FunctionSymbolRefInfo functionRef in symbols) { functionRef.symbol.SymbolBecomeFunction2( FunctionDeclarationSymbol.FunctionArgList, FunctionDeclarationSymbol.FunctionReturnType); } FunctionRefSymbolList.Remove(FunctionDeclarationSymbol.SymbolName); } } foreach (KeyValuePair <string, List <ParserContext.FunctionSymbolRefInfo> > name in FunctionRefSymbolList) { foreach (ParserContext.FunctionSymbolRefInfo funcRef in name.Value) { ErrorModuleIndex = funcRef.module; ErrorLineNumber = funcRef.lineNumber; return(CompileErrors.eCompileMultiplyDeclaredFunction); } } // type check and type inference for (int i = 0; i < FunctionBodyRecords.Count; i++) { int module = ModuleIndices[i]; SymbolRec SymbolTableEntryForForm = SymbolTableEntriesForForm[i]; ASTExpression FunctionBodyRecord = FunctionBodyRecords[i]; int InitialLineNumberOfForm = InitialLineNumbersOfForm[i]; ErrorModuleIndex = module; /* SymbolTableEntryForForm will be the symbol table entry that */ /* was added to the symbol table. FunctionBodyRecord is either */ /* an expression for a function or NIL if it was a prototype */ Debug.Assert(!CodeCenter.CodeCenterHaveThisFunction(SymbolTableEntryForForm.SymbolName)); /* step 1: do type checking */ DataTypes ResultingType; CompileErrors Error = FunctionBodyRecord.TypeCheck( out ResultingType, out ErrorLineNumber); if (Error != CompileErrors.eCompileNoError) { return(Error); } /* check to see that resulting type matches declared type */ if (!CanRightBeMadeToMatchLeft(SymbolTableEntryForForm.FunctionReturnType, ResultingType)) { ErrorLineNumber = InitialLineNumberOfForm; return(CompileErrors.eCompileTypeMismatch); } /* if it has to be promoted, then promote it */ if (MustRightBePromotedToLeft(SymbolTableEntryForForm.FunctionReturnType, ResultingType)) { /* insert promotion operator above expression */ ASTExpression ReplacementExpr = PromoteTheExpression( ResultingType, SymbolTableEntryForForm.FunctionReturnType, FunctionBodyRecord, InitialLineNumberOfForm); FunctionBodyRecord = ReplacementExpr; /* sanity check */ Error = FunctionBodyRecord.TypeCheck( out ResultingType, out ErrorLineNumber); if (Error != CompileErrors.eCompileNoError) { // type promotion caused failure Debug.Assert(false); throw new InvalidOperationException(); } if (ResultingType != SymbolTableEntryForForm.FunctionReturnType) { // after type promotion, types are no longer the same Debug.Assert(false); throw new InvalidOperationException(); } } } // code generation CILAssembly cilAssembly = null; if (CILObject.EnableCIL) { cilAssembly = new CILAssembly(); } FuncCodeRec[] TheWholeFunctionThings = new FuncCodeRec[FunctionBodyRecords.Count]; for (int i = 0; i < FunctionBodyRecords.Count; i++) { int module = ModuleIndices[i]; SymbolRec SymbolTableEntryForForm = SymbolTableEntriesForForm[i]; ASTExpression FunctionBodyRecord = FunctionBodyRecords[i]; int InitialLineNumberOfForm = InitialLineNumbersOfForm[i]; string Filename = Filenames[module]; object Signature = Signatures[module]; ErrorModuleIndex = module; Debug.Assert(!CodeCenter.CodeCenterHaveThisFunction(SymbolTableEntryForForm.SymbolName)); /* step 1.5: optimize the AST */ OptimizeAST(ref FunctionBodyRecord); /* step 2: do code generation */ /* calling conventions: */ /* - push the arguments */ /* - funccall pushes the return address */ /* thus, upon entry, Stack[0] will be the return address */ /* and Stack[-1] will be the rightmost argument */ /* on return, args and retaddr are popped and retval replaces them */ int StackDepth = 0; int MaxStackDepth = 0; int ReturnValueLocation = StackDepth; /* remember return value location */ int ArgumentIndex = 0; SymbolListRec FormalArgumentListScan = SymbolTableEntryForForm.FunctionArgList; while (FormalArgumentListScan != null) { SymbolRec TheFormalArg = FormalArgumentListScan.First; StackDepth++; /* allocate first */ MaxStackDepth = Math.Max(MaxStackDepth, StackDepth); TheFormalArg.SymbolVariableStackLocation = StackDepth; /* remember */ ArgumentIndex++; FormalArgumentListScan = FormalArgumentListScan.Rest; } /* reserve return address spot */ StackDepth++; MaxStackDepth = Math.Max(MaxStackDepth, StackDepth); /* allocate the function code */ PcodeRec TheFunctionCode = new PcodeRec(); FunctionBodyRecord.PcodeGen( TheFunctionCode, ref StackDepth, ref MaxStackDepth); Debug.Assert(StackDepth <= MaxStackDepth); /* 2 extra words for retaddr and resultofexpr */ if (StackDepth != ArgumentIndex + 1 + 1) { // stack depth error after evaluating function Debug.Assert(false); throw new InvalidOperationException(); } /* now put the return instruction (pops retaddr and args, leaving retval) */ int ignored; TheFunctionCode.AddPcodeInstruction(Pcodes.epReturnFromSubroutine, out ignored, InitialLineNumberOfForm); TheFunctionCode.AddPcodeOperandInteger(ArgumentIndex); StackDepth = StackDepth - (1 + ArgumentIndex); Debug.Assert(StackDepth <= MaxStackDepth); if (StackDepth != 1) { // stack depth is wrong at end of function Debug.Assert(false); throw new InvalidOperationException(); } TheFunctionCode.MaxStackDepth = MaxStackDepth; /* step 2.5: optimize the code */ TheFunctionCode.OptimizePcode(); /* step 3: create the function and save it away */ FuncCodeRec TheWholeFunctionThing = new FuncCodeRec( SymbolTableEntryForForm.SymbolName, SymbolTableEntryForForm.FunctionArgList, TheFunctionCode, SymbolTableEntryForForm.FunctionReturnType, Filename); TheWholeFunctionThings[i] = TheWholeFunctionThing; if (CILObject.EnableCIL) { DataTypes[] argsTypes; string[] argsNames; SymbolicArgListToType(SymbolTableEntryForForm, out argsTypes, out argsNames); CILObject cilObject = new CILObject( CodeCenter.ManagedFunctionLinker, argsTypes, argsNames, SymbolTableEntryForForm.FunctionReturnType, FunctionBodyRecord, cilAssembly, false /*argsByRef*/); TheWholeFunctionThing.CILObject = cilObject; } } // register after entire assembly is emitted if (CILObject.EnableCIL) { cilAssembly.Finish(); } for (int i = 0; i < TheWholeFunctionThings.Length; i++) { FuncCodeRec TheWholeFunctionThing = TheWholeFunctionThings[i]; object Signature = Signatures[ModuleIndices[i]]; CodeCenter.AddFunctionToCodeCenter(TheWholeFunctionThing, Signature); } // retain signatures for compilation of special functions CodeCenter.RetainedFunctionSignatures = new KeyValuePair <string, FunctionSignature> [SymbolTableEntriesForForm.Count]; for (int i = 0; i < CodeCenter.RetainedFunctionSignatures.Length; i++) { DataTypes[] argsTypes; string[] argsNames; SymbolicArgListToType(SymbolTableEntriesForForm[i], out argsTypes, out argsNames); CodeCenter.RetainedFunctionSignatures[i] = new KeyValuePair <string, FunctionSignature>( SymbolTableEntriesForForm[i].SymbolName, new FunctionSignature( argsTypes, SymbolTableEntriesForForm[i].FunctionReturnType)); } return(CompileErrors.eCompileNoError); }
public override bool EnsureBuilt( bool force, PcodeSystem.IEvaluationContext pcodeEnvironment, BuildFailedCallback failedCallback) { if (!force && (WaveTableData != null)) { return(true); } WaveTableData = null; PcodeRec FuncCode; if (!BuildCode(failedCallback, out FuncCode)) { return(false); } using (ParamStackRec ParamList = new ParamStackRec()) { ArrayHandleFloat dataHandle = new ArrayHandleFloat(new float[NumFrames * NumTables]); int initialCapacity = 1 /*frames*/ + 1 /*tables*/ + 1 /*data*/ + 1 /*retaddr*/; ParamList.EmptyParamStackEnsureCapacity(initialCapacity); ParamList.AddIntegerToStack(NumFrames); ParamList.AddIntegerToStack(NumTables); ParamList.AddArrayToStack(dataHandle); ParamList.AddIntegerToStack(0); /* return address placeholder */ CodeCenterRec CodeCenter = ((Document)Parent).CodeCenter; EvalErrInfoRec ErrorInfo; EvalErrors EvaluationError = PcodeSystem.EvaluatePcodeThread.EvaluatePcode( ParamList, FuncCode, CodeCenter, out ErrorInfo, pcodeEnvironment); if (EvaluationError != EvalErrors.eEvalNoError) { failedCallback( this, new PcodeEvaluationErrorInfo( EvaluationError, ErrorInfo, FuncCode, CodeCenter)); return(false); } Debug.Assert(ParamList.GetStackNumElements() == initialCapacity); // args - retaddr + return value #if DEBUG ParamList.Elements[2].AssertFloatArray(); #endif dataHandle = ParamList.Elements[2].reference.arrayHandleFloat; WaveTableData = new WaveTableStorageRec(NumTables, NumFrames, NumBitsType.eSample24bit); float[] NewData = dataHandle.floats; if (NewData.Length != NumTables * NumFrames) { failedCallback( this, new PcodeEvaluationErrorInfo( "<anonymous>", PcodeSystem.GetPcodeErrorMessage(EvalErrors.eEvalArrayWrongDimensions), 1)); return(false); } for (int i = 0; i < NumTables; i++) { WaveTableStorageRec.Table table = WaveTableData.ListOfTables[i]; for (int j = 0; j < NumFrames; j++) { table[j] = NewData[i * NumFrames + j]; } } } return(true); }
public override bool EnsureBuilt( bool force, PcodeSystem.IEvaluationContext pcodeEnvironment, BuildFailedCallback failedCallback) { if (!force && (SampleData != null)) { return(true); } SampleData = null; PcodeRec FuncCode; if (!BuildCode(failedCallback, out FuncCode)) { return(false); } using (ParamStackRec ParamList = new ParamStackRec()) { ArrayHandleFloat dataHandleLeft = new ArrayHandleFloat(new float[0]); ArrayHandleFloat dataHandleRight = new ArrayHandleFloat(new float[0]); int initialCapacity = 1 /*loopstart1*/ + 1 /*loopstart2*/ + 1 /*loopstart3*/ + 1 /*loopend1*/ + 1 /*loopend2*/ + 1 /*loopend3*/ + 1 /*origin*/ + 1 /*samplingrate*/ + 1 /*naturalfrequency*/ + (NumChannels == NumChannelsType.eSampleStereo ? 2 : 1) /*data or leftdata/rightdata */ + 1 /*retaddr*/; ParamList.EmptyParamStackEnsureCapacity(initialCapacity); ParamList.AddIntegerToStack(LoopStart1); ParamList.AddIntegerToStack(LoopStart2); ParamList.AddIntegerToStack(LoopStart3); ParamList.AddIntegerToStack(LoopEnd1); ParamList.AddIntegerToStack(LoopEnd2); ParamList.AddIntegerToStack(LoopEnd3); ParamList.AddIntegerToStack(Origin); ParamList.AddIntegerToStack(SamplingRate); ParamList.AddDoubleToStack(NaturalFrequency); if (NumChannels == NumChannelsType.eSampleStereo) { ParamList.AddArrayToStack(dataHandleLeft); ParamList.AddArrayToStack(dataHandleRight); } else { ParamList.AddArrayToStack(dataHandleLeft); } ParamList.AddIntegerToStack(0); /* return address placeholder */ CodeCenterRec CodeCenter = ((Document)Parent).CodeCenter; EvalErrInfoRec ErrorInfo; EvalErrors EvaluationError = PcodeSystem.EvaluatePcodeThread.EvaluatePcode( ParamList, FuncCode, CodeCenter, out ErrorInfo, pcodeEnvironment); if (EvaluationError != EvalErrors.eEvalNoError) { failedCallback( this, new PcodeEvaluationErrorInfo( EvaluationError, ErrorInfo, FuncCode, CodeCenter)); return(false); } Debug.Assert(ParamList.GetStackNumElements() == initialCapacity); // args - retaddr + return value #if DEBUG ParamList.Elements[9].AssertFloatArray(); #endif dataHandleLeft = ParamList.Elements[9].reference.arrayHandleFloat; if (NumChannels == NumChannelsType.eSampleStereo) { #if DEBUG ParamList.Elements[10].AssertFloatArray(); #endif dataHandleRight = ParamList.Elements[10].reference.arrayHandleFloat; } if (NumChannels == NumChannelsType.eSampleStereo) { float[] Left = dataHandleLeft.floats; float[] Right = dataHandleRight.floats; if (Left.Length != Right.Length) { failedCallback( this, new PcodeEvaluationErrorInfo( "<anonymous>", "Left and Right algorithmic sample arrays are not the same size.", 1)); return(false); } SampleData = new SampleStorageActualRec(Left.Length, NumBitsType.Max, NumChannels); for (int i = 0; i < Left.Length; i++) { SampleData[2 * i + 0] = Left[i]; SampleData[2 * i + 1] = Right[i]; } } else { float[] Mono = dataHandleLeft.floats; SampleData = new SampleStorageActualRec(Mono.Length, NumBitsType.Max, NumChannels); for (int i = 0; i < Mono.Length; i++) { SampleData[i] = Mono[i]; } } } return(true); }
public PcodeEvaluationErrorInfo(EvalErrors EvaluationError, EvalErrInfoRec ErrorInfo, PcodeRec AnonymousFunction, CodeCenterRec CodeCenter) { int ErrorLineNumberEvaluation; string Name; FuncCodeRec ErrorFunction = CodeCenter.GetFunctionFromOpcode(ErrorInfo.OffendingPcode); if (ErrorFunction != null) { Name = ErrorFunction.GetFunctionFilename(); ErrorLineNumberEvaluation = ErrorFunction.GetFunctionPcode().GetLineNumberForInstruction(ErrorInfo.OffendingInstruction); } else { Name = "<anonymous>"; ErrorLineNumberEvaluation = AnonymousFunction.GetLineNumberForInstruction(ErrorInfo.OffendingInstruction); } this.module = Name; this.errorText = PcodeSystem.GetPcodeErrorMessage(EvaluationError); this.lineNumber = ErrorLineNumberEvaluation; }