void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
{
    int pid = base->getId();
    CallStackType *stack = (CallStackType *) base;

#if 0
    fprintf(stderr, "native pop  t %llu p %d s %d fid %d 0x%x %s\n",
            stack->getGlobalTime(time), pid, stackLevel,
            function->id, function->addr, function->name);
#endif

    FunctionStack *fstack = dmtrace_stack[pid];
    if (fstack == NULL) {
        fstack = new FunctionStack();
        dmtrace_stack[pid] = fstack;
    }

    symbol_type *sym = fstack->pop();
    if (sym != NULL && sym != function) {
        fprintf(stderr, "Error: q2dm function mismatch at time %llu pid %d sym %s\n",
                stack->getGlobalTime(time), pid, sym->name);
        fstack->showStack();
        exit(1);
    }

    thread_time[pid] = time;
    dmtrace->addFunctionExit(function->id, time, pid);
}
void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
{
    int pid = base->getId();
    CallStackType *stack = (CallStackType *) base;

#if 0
    fprintf(stderr, "native push t %llu p %d s %d fid %d 0x%x %s\n",
            stack->getGlobalTime(time), pid, stackLevel,
            function->id, function->addr, function->name);
#endif

    FunctionStack *fstack = dmtrace_stack[pid];
    if (fstack == NULL) {
        fstack = new FunctionStack();
        dmtrace_stack[pid] = fstack;
    }

    fstack->push(function);
    thread_time[pid] = time;
    dmtrace->addFunctionEntry(function->id, time, pid);
}
Пример #3
0
Calc::NumberStack Calc::eval(Parser &parser) throw(std::string)
{
	NumberStack numStack;
	FunctionStack funcStack;

	string token;

	while(!parser.isDone())
	{
		token = parser.getNextToken();
		if(token.length() == 0)
			break;

		// first check if token is a numeric value
		CalcFloat_t value;
		if(getNumeric(token.data(), value))
		{
			// push numeric value onto stack
			numStack.push(value);
		}
		else if(token.compare("(") == 0)
		{
			// open bracket
			_bracketCount++;
			NumberStack result = eval(parser);
			NumberStack tempStack;

			// push results onto stack (need to reverse order)
			while(!result.empty())
			{
				tempStack.push(result.top());
				result.pop();
			}
			while(!tempStack.empty())
			{
				numStack.push(tempStack.top());
				tempStack.pop();
			}
		}
		else if(token.compare(")") == 0)
		{
			// close bracket
			_bracketCount--;
			break;
		}
		else
		{
			// find the function
			vector<CFunction*>::const_iterator func = findFunction(token);

			if(func != _funcList.end())
			{
				if((*func)->isOperator())
				{
					// evaluate operators while they are of equal or higher precedence
					while(!funcStack.empty())
					{
						// get the top of the operator stack
						const CFunction &op = *funcStack.top();

						// check precedence
						if((*func)->_order > op._order)
							break;

						// pop this operation from the stack
						funcStack.pop();

						// check that there are enough arguments on the stack
						if((int)numStack.size() < op._numArgs)
						{
							// error => not enough elements on stack
							throwSyntaxError(parser);
						}
						else
						{
							// get the function arguments: operators always have <= 2
							assert(op._numArgs <= 2 && "Invalid number of arguments");

							CalcFloat_t args[2];
							for(int i=0;i<op._numArgs;i++)
							{
								args[i] = (CalcFloat_t)numStack.top();
								numStack.pop();
							}

							// do the operation
							CalcFloat_t result = op.eval(args,op._numArgs);
					
							// push the answer onto the stack
							numStack.push(result);
						}
					}

					// push the new operation onto the stack
					funcStack.push(*func);
				}
				else
				{
					// next token MUST be a '('
					token = parser.getNextToken();
					if(token.compare("(") != 0)
						throwSyntaxError(parser);

					_bracketCount++;
					NumberStack argStack = eval(parser);

					const CFunction &op = **func;

					// check that there are enough arguments on the stack
					if((int)argStack.size() < op._numArgs)
					{
						// error => not enough elements on stack
						throwSyntaxError(parser);
					}
					else
					{
						assert(op._numArgs == 1 && "Invalid number of arguments");

						CalcFloat_t args[1];
						for(int i=0;i<op._numArgs;i++)
						{
							args[i] = (CalcFloat_t)argStack.top();
							argStack.pop();
						}

						// do the operation
						CalcFloat_t result = op.eval(args,op._numArgs);
						
						// push the answer onto the stack
						numStack.push(result);
					}
				}
			}
			else
			{
				// invalid input
				throw (string("Unknown token ") + token);
			}
		}
	}

	// collapse function stack

	// evaluate operators while they are of equal or higher precedence
	while(!funcStack.empty())
	{
		// get the top of the operator stack
		const CFunction &op = *funcStack.top();

		// pop this operation from the stack
		funcStack.pop();

		// check that there are enough arguments on the stack
		if((int)numStack.size() < op._numArgs)
		{
			// error => not enough elements on stack
			throwSyntaxError(parser);
		}
		else
		{
			// get the function arguments: operators always have 2
			assert(op._numArgs <= 2 && "Invalid number of arguments");

			CalcFloat_t args[2];
			for(int i=0;i<op._numArgs;i++)
			{
				args[i] = (CalcFloat_t)numStack.top();
				numStack.pop();
			}

			// do the operation
			CalcFloat_t result = op.eval(args,op._numArgs);
	
			// push the answer onto the stack
			numStack.push(result);
		}
	}

	// function stack should now be empty
	if(!funcStack.empty())
		throwSyntaxError(parser);

	return numStack;
}