Exemplo n.º 1
0
int main(int argc, char ** argv)
{
	char op;
	char mStr[1024];
	matrix ans, m1, m2;
	int sc = 0;

	if(argc > 1){
		op = getOp(argv[1]);
	} else {
		printf("Which operation: ");
		op = getOp(NULL);
	}


	printf("First matrix:\n");
	scanf("%s", mStr);
	m1 = MatrixInit(mStr);

	if(op == 'a' || op == 's' || op == 'm'){
		printf("Second matrix:\n");
		scanf("%s", mStr);
		m2 = MatrixInit(mStr);
	} else if(op == 'c') {
		printf("Scalar multiple:\n");
		scanf("%d", &sc);
	}

	switch(op){
		case 'a':
			ans = MatrixAdd(m1, m2);
			break;
		case 's':
			ans = MatrixSub(m1, m2);
			break;
		case 'm':
			ans = MatrixMul(m1, m2);
			break;
		case 'i':
			ans = MatrixInv(m1);
			break;
		case 'c':
			ans = MatrixSMul(m1, i2f(sc));
			break;
		default:
			printf("Something went very wrong.\n");
			return 1;
	}

	printf("Answer:\n");
	MatrixPrint(ans);

	MatrixFree(m1);
	MatrixFree(ans);
	if(op == 'a' || op == 's' || op == 'm'){
		MatrixFree(m2);
	}

	return 0;
}
Exemplo n.º 2
0
ExprTree * getTree()
{
    int      lex;
    int      opcode;
    ExprTree *left;
    ExprTree *right;
    ExprTree *node;

    left = getOp(&lex);
    for (;;)
    {
        if ( lex == 0 || lex == 2 )
        {
            if ( lex == 2 ) Bc--;
            break;
        }

        if (lex != 3 && lex != 4 )
        {
            Err = 1;
            break;
        }

        opcode = lex;
        right = getOp(&lex);
        node = newNode();
        if (Err) break;
        node->left = left;
        node->right = right;
        node->opcode = opcode;
        left = node;
    } 
    return left;
}
Exemplo n.º 3
0
	void Move::checkOp(string toTest) {
		Parse_Strings p;
		if (toTest.find(getOp()) != string::npos) {
			vector<string> use(2);
			use = p.split_string(toTest, getOp());
			moveTo(use[0], use[1]);
			p.test(p.getCheck());
		}
	}
TEST(IfElseBuilding, CanBuildWithIfAsFirstParameter) {
	spOp ifOp(new If(getOp("drop")));
	IfElse ifElseOp(ifOp, getOp("swap"));

	values.push(4);
	values.push(9);
	values.push(1);

	ifElseOp.invoke(values);

	LONGS_EQUAL(4, values.top());
}
Exemplo n.º 5
0
int main(int argc, char** argv)
{
	int i,j,tem, flag=0, res[2];
	char c, stem[20];
	++argv;
	
	while(*argv != NULL)
	{
		flag=0;
		c=*argv[0];
		switch(c)
		{
			case '+':
				getOp(res);
/*				printf("\nAdd ");*/
				push(res[0]+res[1]);
				break;
			case '-':
/*				printf("\nSub ");*/
				getOp(res);
				push(res[0]-res[1]);
				break;
			case 'x':
/*				printf("\nMul ");*/
				getOp(res);
				push(res[0]*res[1]);
				break;
			case '/':
/*				printf("\nDivide ");*/
				getOp(res);
				push(res[0]/res[1]);
				break;
			default:
/*				printf("\nDefault ");*/
				flag=1;
				break;
		}
		if(flag)
			push(atoi(*argv));
		
/*		printf("\nTop is %d ",top);*/
		
/*		printf("\nEle\n");*/
/*		for(i=0;i<top;i++)*/
/*			printf("  %d  ",stk[i]);*/
		
			
		++argv;
	}
	if(!flag)
	printf("%d\n",pop());
}
void WorkloadGenerator::addConstraint(simple_filter *filter, set<int> &alreadyConsidered) {
  int nameRand = 0;
  bool isNew;
  do {
    if (paramHandler->getZipfNames()) nameRand = getZipf(1, paramHandler->getNumNames())-1;
    else nameRand = rand()%paramHandler->getNumNames();
    // check if this name has already been used in this filter
    if (alreadyConsidered.find(nameRand)==alreadyConsidered.end()) isNew=true;
    else isNew=false;
  } while(!isNew);
  alreadyConsidered.insert(nameRand);
  siena::type_id type = getType(nameRand);
  siena::operator_id opId = getOp(type);
  siena::string_t name = names[nameRand];
  simple_op_value *opValue;
  if (type==siena::int_id) {
    siena::int_t intVal = rand()%paramHandler->getNumAttVal();
    opValue = new simple_op_value(opId, intVal);
  } else {
    int stringValRand = rand()%paramHandler->getNumAttVal();
    siena::string_t stringVal = stringValues[stringValRand];
    opValue = new simple_op_value(opId, stringVal);
  }
  filter->add(name, opValue);
}
Exemplo n.º 7
0
void interpOne(IRGS& env,
               folly::Optional<Type> outType,
               int popped,
               int pushed,
               InterpOneData& idata) {
  auto const unit = curUnit(env);
  spillStack(env);
  env.irb->exceptionStackBoundary();
  auto const op = unit->getOp(bcOff(env));

  idata.bcOff = bcOff(env);
  idata.cellsPopped = popped;
  idata.cellsPushed = pushed;
  idata.opcode = op;

  gen(
    env,
    opcodeChangesPC(idata.opcode) ? InterpOneCF : InterpOne,
    outType,
    idata,
    sp(env),
    fp(env)
  );
  assertx(env.irb->stackDeficit() == 0);
}
Exemplo n.º 8
0
void InstArithmetic::dump(const Cfg *Func) const {
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = " << InstArithmeticAttributes[getOp()].DisplayString << " "
      << getDest()->getType() << " ";
  dumpSources(Func);
}
Exemplo n.º 9
0
AutoGetCollectionForRead::~AutoGetCollectionForRead() {
    // Report time spent in read lock
    auto currentOp = CurOp::get(_txn);
    Top::get(_txn->getClient()->getServiceContext())
        .record(currentOp->getNS(),
                currentOp->getOp(),
                -1,  // "read locked"
                _timer.micros(),
                currentOp->isCommand());
}
Exemplo n.º 10
0
/**
 * The main function that runs when program is being run
 */
int main()
{
	MatrixOperation selectedOp = getOp();
	string errorStr = selectedOp._opHandler(selectedOp);
	if (errorStr != EMPTY_STRING)
	{  // If operation failed, print the error message.
		cout << "Error: " << selectedOp._name << " failed - " << errorStr << "." << endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
Exemplo n.º 11
0
OldClientContext::~OldClientContext() {
    // Lock must still be held
    invariant(_txn->lockState()->isLocked());

    auto currentOp = CurOp::get(_txn);
    Top::get(_txn->getClient()->getServiceContext())
        .record(currentOp->getNS(),
                currentOp->getOp(),
                _txn->lockState()->isWriteLocked() ? 1 : -1,
                _timer.micros(),
                currentOp->isCommand());
}
Exemplo n.º 12
0
char *TKGetNextToken( TokenizerT * tk ) {
	
	if(tk->str[tk->pindex] == ' ' || tk->str[tk->pindex] == '\t' || tk->str[tk->pindex] == '\v' || tk->str[tk->pindex] == '\f' || tk->str[tk->pindex] == '\n' || tk->str[tk->pindex] == '\r'){
		tk->pindex++;
		return NULL;
	}

	int charIndex = 0;
	char *tmp = (char*)malloc(sizeof(char)*strlen(tk->str));
	if(isalnum(tk->str[tk->pindex])){
		if(isalpha(tk->str[tk->pindex])){ //checks for word
			tmp[charIndex] = tk->str[tk->pindex];
			charIndex++;
			tk->pindex++;
			tmp = getWord(tk, tmp, charIndex);
			return tmp;
		}else{
			if(tk->str[tk->pindex] == '0' && isalnum(tk->str[tk->pindex + 1])){ //checks for hex
				if(tk->str[tk->pindex + 1] == 'x' || tk->str[tk->pindex + 1] == 'X'){
					if(isdigit(tk->str[tk->pindex + 2]) || tk->str[tk->pindex + 2] == 'a' || tk->str[tk->pindex + 2] == 'b' || tk->str[tk->pindex + 2] == 'c' || tk->str[tk->pindex + 2] == 'd' || tk->str[tk->pindex + 2] == 'e' || tk->str[tk->pindex + 2] == 'f'){ 
						tmp[charIndex] = tk->str[tk->pindex];
						charIndex++;
						tk->pindex++;
						tmp = getHex(tk, tmp, charIndex);
						return tmp;
					}
				}else if(tk->str[tk->pindex + 1] == '0' || tk->str[tk->pindex + 1] == '1' || tk->str[tk->pindex + 1] == '2' || tk->str[tk->pindex + 1] == '3' || tk->str[tk->pindex + 1] == '4' || tk->str[tk->pindex + 1] == '5' || tk->str[tk->pindex + 1] == '6' || tk->str[tk->pindex + 1] == '7'){ // checks for octal
					tmp[charIndex] = tk->str[tk->pindex];
					charIndex++;
					tk->pindex++;
					tmp = getOctal(tk, tmp, charIndex);
					return tmp;
				}
			}
		}
		//if not sends to number(decimal or floats)
		tmp[charIndex] = tk->str[tk->pindex];
		charIndex++;
		tk->pindex++;
		tmp = getNumber(tk, tmp, charIndex);
		return tmp;	
	}else{
		// C-Operators
		tmp = getOp(tk, tmp, charIndex);
	}

	return tmp;
}
Exemplo n.º 13
0
  void SXNode::canInline(std::map<const SXNode*, int>& nodeind) const {
    // Add or mark node in map
    std::map<const SXNode*, int>::iterator it=nodeind.find(this);
    if (it==nodeind.end()) {
      // First time encountered, mark inlined
      nodeind.insert(it, make_pair(this, 0));

      // Handle dependencies with recursion
      for (int i=0; i<ndep(); ++i) {
        dep(i)->canInline(nodeind);
      }
    } else if (it->second==0 && getOp()!=OP_PARAMETER) {
      // Node encountered before, do not inline (except if symbolic primitive)
      it->second = -1;
    }
  }
Exemplo n.º 14
0
int main(int argc, char const *argv[])
{
	/* code */
	int tab[max];

	int opr ;
	if (argv[1] == NULL) opr =1;
	else opr = getOp(argv[1]);

	for (int i=0;i<max;i++)
	{
		tab[i] = i;
	}

	save(createLine(opr,tab,op(opr,tab)),tab);
    printf("\nDone\n\n");

	return 0;
}
Exemplo n.º 15
0
void abstract_interpreter_method_info::init(byteVectorOop c, objVectorOop l) {
     codes_object = c;
  literals_object = l;
  codes           = (unsigned char*)codes_object->bytes();
  literals        = literals_object->objs();
  length_codes    =    codes_object->length();
  length_literals = literals_object->length();
  
  if (codes_object->length() == 0)
    instruction_set = TWENTIETH_CENTURY_INSTRUCTION_SET;
  else {
    char first_code = codes_object->byte_at(0);
    instruction_set =     getOp((u_char)first_code) == INSTRUCTION_SET_SELECTION_CODE
                        ? (InstructionSetKind) getIndex(first_code)
                        : TWENTIETH_CENTURY_INSTRUCTION_SET;
    assert( instruction_set == TWENTIETH_CENTURY_INSTRUCTION_SET
        ||  0 <= instruction_set  &&  instruction_set <= LAST_INSTRUCTION_SET,
        "bad instruction set");
  }    
}
Exemplo n.º 16
0
void abstract_interpreter_method_info::init(ByteVectorOop c, ObjVectorOop l) {
     codes_object = c;
  literals_object = l;
  codes           = (unsigned char*) ByteVectorLayout().for_AddressOfIndexableAt(codes_object, 0);
  literals        =  ObjVectorLayout().for_AddressOfIndexableAt(literals_object, 0);
  length_codes    = ByteVectorLayout().indexableSizeOf(   codes_object);
  length_literals =  ObjVectorLayout().indexableSizeOf(literals_object);
  
  if (length_codes == 0) {
    instruction_set = TWENTIETH_CENTURY_INSTRUCTION_SET;
  }
  else {
    char first_code = ByteVectorLayout().for_IndexableAt(codes_object, 0);
    instruction_set =     getOp((u_char)first_code) == INSTRUCTION_SET_SELECTION_CODE
                        ? (InstructionSetKind) getIndex(first_code)
                        : TWENTIETH_CENTURY_INSTRUCTION_SET;
    always_assert( instruction_set == TWENTIETH_CENTURY_INSTRUCTION_SET
                  ||  0 <= instruction_set  &&  instruction_set <= LAST_INSTRUCTION_SET,
                 "bad instruction set");
  }    
}
Exemplo n.º 17
0
int main(int argc, char** argv)
{
    int i;
    struct symbol s;

    if (argc < 2) {
	printf ("Expected at least one argument...\n");
	return 0;
    }

    for (i=0; i <= strlen(argv[1]); i++) {
	s = getOp(argv[1][i]);
	if (s.type == NUMBER)
	    printf ("Integer: %d\n", s.ival);
	if (s.type == OPERATOR)
	    printf ("Operator: '%c'\n", s.cval);
	if (s.type == FLOAT)
	    printf ("Float: %f\n",s.fval);
    }
    return 0;
}
Exemplo n.º 18
0
void interpOne(IRGS& env,
               folly::Optional<Type> outType,
               int popped,
               int pushed,
               InterpOneData& idata) {
  auto const unit = curUnit(env);
  auto const op = unit->getOp(bcOff(env));

  idata.bcOff = bcOff(env);
  idata.cellsPopped = popped;
  idata.cellsPushed = pushed;
  idata.opcode = op;

  gen(
    env,
    opcodeChangesPC(idata.opcode) ? InterpOneCF : InterpOne,
    outType,
    idata,
    sp(env),
    fp(env)
  );
}
Exemplo n.º 19
0
//processes a statement 
void processString(char *str){
	Var *tmp = variables, *var1, *var2;
	int varLen, opLen, isNumeric, var3;
	char *lValue, *op, *rValue;

	lValue = getVarName(str);
	varLen = strlen(lValue);

	op = getOp(str, varLen);
	opLen = strlen(op);

	rValue = getRValue(str, varLen, opLen);
	var1 = getVar(lValue);
	isNumeric = isnumeric(rValue);
	if(1 == isNumeric){
		var3 = atoi(rValue);
	}
	else{
		var2 = getVar(rValue);
		var3 = var2->value;
	}

	switch(op[0]){
		case '+':
			var1->value+=var3;
			break;
		case '-':
			var1->value-=var3;
			break;
		case '*':
			var1->value*=var3;
			break;
		case '/':
			var1->value/=var3;
			break;
	}
} 
Exemplo n.º 20
0
/* fixa diverse opmoden
** postinc och predec
** minne,minne
*/
static void doOpModes(void)
{
	INPUT *in;
	OPERAND op1,op2,rop1,rop2;
	/* 1. l�s instruktion */
	in=READER();
	if(!in)
		return;

	switch(in->type) {
	case IS_INSTR:
		/* Eleminera PC relativt om m�jligt */
		in->data.instr.op1=fixPC(in->data.instr.op1);
		in->data.instr.op2=fixPC(in->data.instr.op2);
		op1=in->data.instr.op1;
		op2=in->data.instr.op2;
		/* 2. pre op 1 */
		fixPre(in,op1);
		/* 3. get op 1 */
		op1=fixIndex(in,op1);
		rop1=getOp(in,op1);
		/* 4. post op 1 */
		fixPost(in,op1);
		/* 5. pre op 2 */
		fixPre(in,op2);
		/* 6. instruktion */
		rop2=cleanOp(op2);
		rop2=fixIndex(in,rop2);
		genInstr(in,rop1,rop2);
		/* 7. post op 2 */
		fixPost(in,op2);
		break;
	default:
		output(in);
		break;
	}
}
Exemplo n.º 21
0
bool InstArithmetic::isCommutative() const {
  return InstArithmeticAttributes[getOp()].IsCommutative;
}
/*  
 * Subtract From Pointer Immediate
 * Pn <- Pn - XX, X: {0 .. 9}.
 * 
 * 02 Pn XX
 *
 * Pointer decremented by integer XX
 */
void o2(Vm* vm){
    setPointer(vm, charToInt(vm->IR[3]), getPointer(vm, charToInt(vm->IR[3])) - opToInt(getOp(4,vm->IR)));
}
Exemplo n.º 23
0
oop_t ActivationObj::loop(oop_t this_activation) {

  The::set_active_context( this_activation, this);
  
  DECLARE_STACK;
  smi         bci = get_pc_quickly(io);
  
  ActivationMapObj* m_addr = map_addr();
  
  oop_t           codes_oop    = m_addr->codes();
  ByteVectorObj*  codes_addr   = ByteVectorObj::from(codes_oop);
  char*           codes        = codes_addr->bytes();
  fint            codes_length = codes_addr->indexableSize();



  oop_t         literals       = m_addr->literals();
  ObjVectorObj* literals_addr  = ObjVectorObj::from(literals);
  fint          literals_io    = literals_addr->indexableOrigin();
  
 
  fint index = 0, temp_index;
  # define UC_index ((temp_index = index << INDEXWIDTH), (index = 0), temp_index | bc_index)
  bool undirected_resend = false;
  # define UC_undirected_resend (undirected_resend ? (undirected_resend = false, true) : false)
  
  fint lexical_level = 0;
  
  # define use_lit (literals_addr->read_oop(literals_io + UC_index))
  
  oop_t delegatee = 0, temp_del;
  # define UC_del  ((temp_del = delegatee), (delegatee = 0), temp_del)
  
  fint arg_count = 0, temp_arg_count;
  # define UC_arg_count ((temp_arg_count = arg_count), (arg_count = 0), temp_arg_count)
  
  fint temp_bci;
  // for process pre-emption, stop on backward branches
  // todo optimize should probably just stop every 10 or 100 backward branches, or even just every N bytecodes
  # define set_bci(bci_oop) (temp_bci = value_of_smiOop(assert_smi(bci_oop)), stop = temp_bci < bci, bci = temp_bci)
  
  oop_t self = get_self_quickly(io);
  oop_t rcvr = get_rcvr_quickly(io);
  for ( bool stop = false; !stop; ) {
    if (bci >= codes_length) {
      oop_t r = pop();
      oop_t s = get_sender_quickly(io);
      if (s != NULL) // it'll be NULL if we're returning from the start method
        ActivationObj::from(s)->remote_push(r);
      // todo optimize time slow; quits this routine just for a return -- dmu 1/06
      return s;
    }
    unsigned char bc = codes[bci++];
    ByteCodeKind kind  = getOp(bc);
    fint         bc_index = getIndex(bc);
    // printf("interpreting a bytecode in activationMap %i, bc is %i, kind is %i, bc_index is %i\n", map_oop(), bc, kind, bc_index);
    switch (kind) {
     default:   fatal("unknown kind of bytecode"); break;
     
     case                   INDEX_CODE:          index = UC_index;     break;
     case           LEXICAL_LEVEL_CODE:  lexical_level = UC_index;     break;
     case          ARGUMENT_COUNT_CODE:      arg_count = UC_index;     break;
  
     case           READ_LOCAL_CODE:   push(local_obj_addr(lexical_level)-> read_arg_or_local(UC_index)      );  lexical_level = 0;               break;
     case          WRITE_LOCAL_CODE:        local_obj_addr(lexical_level)->write_arg_or_local(UC_index, pop());  lexical_level = 0;  push(self);  break;
     
     case          BRANCH_CODE:                                                          set_bci(use_lit);                   break;
     case          BRANCH_TRUE_CODE:     if ( pop() == The::oop_of(The:: true_object))   set_bci(use_lit);  else index = 0;  break;
     case          BRANCH_FALSE_CODE:    if ( pop() == The::oop_of(The::false_object))   set_bci(use_lit);  else index = 0;  break;
     case          BRANCH_INDEXED_CODE:
                                        {
                                         ObjVectorObj* branch_vector_addr = ObjVectorObj::from(assert_objVector(use_lit));
                                         oop_t branch_index_oop = pop();
                                         if ( is_smi(branch_index_oop) ) {
                                            smi branch_index = value_of_smiOop(branch_index_oop);
                                            if (  0 <= branch_index  &&  branch_index < branch_vector_addr->indexableSize()  )   {
                                              oop_t dest_oop = branch_vector_addr->indexable_at(branch_index);
                                              set_bci(dest_oop);
                                            }
                                         }
                                        }
                                        break;
       
     
     case      DELEGATEE_CODE:               delegatee = use_lit;                                     break;


     case LITERAL_CODE:
      {
       oop_t lit = use_lit;
       if (::is_block(lit)) {
         put_sp_quickly(io, sp); // make sure that the sp is stored correctly, because an allocation could trigger a GC
         oop_t cloned_block = BlockObj::clone_block(lit, this_activation);
         ActivationObj* possibly_moved_act_addr = ActivationObj::from(this_activation); // mightHaveScavengedTheActivation
         if (possibly_moved_act_addr != this) {
           possibly_moved_act_addr->remote_push(cloned_block);
           possibly_moved_act_addr->put_pc_quickly( io, bci );
           return this_activation;
         } else {
           push(cloned_block);
         }
       } else {
         push(lit);
       }
      }
      break;
     
     case IMPLICIT_SEND_CODE:
      // fall through
     case SEND_CODE:
     {
      oop_t selector = use_lit;
      if (selector == The::oop_of(The::restart_selector)) {
        put_sp_quickly( io,  sp  = first_stack_offset               );
        put_pc_quickly( io,  bci = get_pc_after_endInit_quickly(io) );
        break;
      }
      put_sp_quickly( io, sp );
      // todo optimize dmu 3/6. This is here for the _Breakpoint primitve to help debugging by storing the PC.
      // But it slows every primitive, sigh.
      put_pc_quickly( io, bci);

      oop_t a = send(kind == IMPLICIT_SEND_CODE, selector, UC_undirected_resend, UC_del, UC_arg_count, this_activation); 
      if (a != this_activation || ActivationObj::from(a) != this) { // mightHaveScavengedTheActivation
        // put_pc_quickly( io, bci); // commented out after I added the put_pc_quickly above, dmu 3/6
        return a;
      }
      sp = get_sp_quickly(io);
     }
     break;
      
     case NO_OPERAND_CODE:
      switch(bc_index) {
       default: fatal("???"); break;
        case               POP_CODE:      pop();                                  break;
        case              SELF_CODE:      push(self);                             break;
        case          END_INIT_CODE:      put_pc_after_endInit_quickly(io, bci);  break;

        case   NONLOCAL_RETURN_CODE:      return nonlocal_return(pop(), rcvr);    break;
        case UNDIRECTED_RESEND_CODE:      undirected_resend = true;               break;
       }
       break;

    }
  }
  put_sp_quickly( io, sp  );
  put_pc_quickly( io, bci );
  return this_activation;
}
Exemplo n.º 24
0
Arquivo: expr.c Projeto: sjy123/nemu
uint32_t eval(uint32_t p,uint32_t q){
//	Log("%d %d\n",p,q);
	assert(p<=q);
	if (p==q) { //解析数字

		uint32_t n;
		if(tokens[q].type == INT_16)
			sscanf(tokens[q].str,"%x",&n);
		else if (tokens[q].type == INT_10) {
			sscanf(tokens[q].str,"%d",&n);
		}else{
			int i=0;int flag=-1;
			for (; i < 8; i++) {
				if (strcmp(*(regsl+i),tokens[q].str)==0) {
					flag = 1;
					break;
				}
			}
			if (flag) { //找到
				switch(i){
					case 0:return cpu.eax;
					case 1:return cpu.ecx;
					case 2:return cpu.edx;
					case 3:return cpu.ebx;
					case 4:return cpu.esp;
					case 5:return cpu.ebp;
					case 6:return cpu.esi;
					case 7:return cpu.edi;
				}
			}else
			{
				panic("reg can not find error");
			}

		}
		return n;

	}else if(check_parentheses(p,q) == true){ //判断括号
			return eval(p+1,q-1);
	}else if (tokens[p].type =='!') {
		return !eval(++p,q);
	}else if (tokens[p].type == DEREF) {
		return swaddr_read(eval(++p,q),4);
	}else{ //递归计算
			uint32_t op = getOp(p,q); //获取dominat operator
			uint32_t val1 = eval(p,op-1);
			uint32_t val2 = eval(op+1,q);
	//		printf("\n%u %c %u\n",val1,tokens[op].type,val2);

			switch(tokens[op].type){
				case '+':return val1+val2;
				case '-':return val1-val2;
				case '*':return val1*val2;
				case '/':return val1/val2;
				case EQ:return val1==val2;
				case NEQ:return val1!=val2;
				case AND:return val1&&val2;
				case OR:return val1||val2;
				default: assert(0);
			}
	}
}
Exemplo n.º 25
0
Array createBacktrace(const BacktraceArgs& btArgs) {
  auto bt = Array::Create();
  folly::small_vector<c_WaitableWaitHandle*, 64> visitedWHs;

  // If there is a parser frame, put it at the beginning of the backtrace.
  if (btArgs.m_parserFrame) {
    bt.append(
      make_map_array(
        s_file, btArgs.m_parserFrame->filename,
        s_line, btArgs.m_parserFrame->lineNumber
      )
    );
  }

  VMRegAnchor _;
  // If there are no VM frames, we're done.
  if (!rds::header() || !vmfp()) return bt;

  int depth = 0;
  ActRec* fp = nullptr;
  Offset pc = 0;

  // Get the fp and pc of the top frame (possibly skipping one frame).

  if (btArgs.m_skipTop) {
    fp = getPrevActRec(vmfp(), &pc, visitedWHs);
    // We skipped over the only VM frame, we're done.
    if (!fp) return bt;
  } else {
    fp = vmfp();
    auto const unit = fp->func()->unit();
    assert(unit);
    pc = unit->offsetOf(vmpc());
  }

  // Handle the top frame.
  if (btArgs.m_withSelf) {
    // Builtins don't have a file and line number.
    if (!fp->func()->isBuiltin()) {
      auto const unit = fp->func()->unit();
      assert(unit);
      auto const filename = fp->func()->filename();

      ArrayInit frame(btArgs.m_parserFrame ? 4 : 2, ArrayInit::Map{});
      frame.set(s_file, Variant{const_cast<StringData*>(filename)});
      frame.set(s_line, unit->getLineNumber(pc));
      if (btArgs.m_parserFrame) {
        frame.set(s_function, s_include);
        frame.set(s_args, Array::Create(btArgs.m_parserFrame->filename));
      }
      bt.append(frame.toVariant());
      depth++;
    }
  }

  // Handle the subsequent VM frames.
  Offset prevPc = 0;
  for (auto prevFp = getPrevActRec(fp, &prevPc, visitedWHs);
       fp != nullptr && (btArgs.m_limit == 0 || depth < btArgs.m_limit);
       fp = prevFp, pc = prevPc,
         prevFp = getPrevActRec(fp, &prevPc, visitedWHs)) {
    // Do not capture frame for HPHP only functions.
    if (fp->func()->isNoInjection()) continue;

    ArrayInit frame(7, ArrayInit::Map{});

    auto const curUnit = fp->func()->unit();
    auto const curOp = curUnit->getOp(pc);
    auto const isReturning =
      curOp == Op::RetC || curOp == Op::RetV ||
      curOp == Op::CreateCont || curOp == Op::Await ||
      fp->localsDecRefd();

    // Builtins and generators don't have a file and line number
    if (prevFp && !prevFp->func()->isBuiltin()) {
      auto const prevUnit = prevFp->func()->unit();
      auto prevFile = prevUnit->filepath();
      if (prevFp->func()->originalFilename()) {
        prevFile = prevFp->func()->originalFilename();
      }
      assert(prevFile);
      frame.set(s_file, Variant{const_cast<StringData*>(prevFile)});

      // In the normal method case, the "saved pc" for line number printing is
      // pointing at the cell conversion (Unbox/Pop) instruction, not the call
      // itself. For multi-line calls, this instruction is associated with the
      // subsequent line which results in an off-by-n. We're subtracting one
      // in order to look up the line associated with the FCall/FCallArray
      // instruction. Exception handling and the other opcodes (ex. BoxR)
      // already do the right thing. The emitter associates object access with
      // the subsequent expression and this would be difficult to modify.
      auto const opAtPrevPc = prevUnit->getOp(prevPc);
      Offset pcAdjust = 0;
      if (opAtPrevPc == Op::PopR ||
          opAtPrevPc == Op::UnboxR ||
          opAtPrevPc == Op::UnboxRNop) {
        pcAdjust = 1;
      }
      frame.set(s_line,
                prevFp->func()->unit()->getLineNumber(prevPc - pcAdjust));
    }

    // Check for include.
    String funcname{const_cast<StringData*>(fp->func()->name())};
    if (fp->func()->isClosureBody()) {
      // Strip the file hash from the closure name.
      String fullName{const_cast<StringData*>(fp->func()->baseCls()->name())};
      funcname = fullName.substr(0, fullName.find(';'));
    }

    // Check for pseudomain.
    if (funcname.empty()) {
      if (!prevFp && !btArgs.m_withPseudoMain) continue;
      else if (!prevFp) funcname = s_main;
      else funcname = s_include;
    }

    frame.set(s_function, funcname);

    if (!funcname.same(s_include)) {
      // Closures have an m_this but they aren't in object context.
      auto ctx = arGetContextClass(fp);
      if (ctx != nullptr && !fp->func()->isClosureBody()) {
        frame.set(s_class, Variant{const_cast<StringData*>(ctx->name())});
        if (fp->hasThis() && !isReturning) {
          if (btArgs.m_withThis) {
            frame.set(s_object, Object(fp->getThis()));
          }
          frame.set(s_type, s_arrow);
        } else {
          frame.set(s_type, s_double_colon);
        }
      }
    }

    bool const mayUseVV = fp->func()->attrs() & AttrMayUseVV;

    auto const withNames = btArgs.m_withArgNames;
    auto const withValues = btArgs.m_withArgValues;
    if (!btArgs.m_withArgNames && !btArgs.m_withArgValues) {
      // do nothing
    } else if (funcname.same(s_include)) {
      if (depth != 0) {
        auto filepath = const_cast<StringData*>(curUnit->filepath());
        frame.set(s_args, make_packed_array(filepath));
      }
    } else if (!RuntimeOption::EnableArgsInBacktraces || isReturning) {
      // Provide an empty 'args' array to be consistent with hphpc.
      frame.set(s_args, empty_array());
    } else {
      auto args = Array::Create();
      auto const nparams = fp->func()->numNonVariadicParams();
      auto const nargs = fp->numArgs();
      auto const nformals = std::min<int>(nparams, nargs);

      if (UNLIKELY(mayUseVV) &&
          UNLIKELY(fp->hasVarEnv() && fp->getVarEnv()->getFP() != fp)) {
        // VarEnv is attached to eval or debugger frame, other than the current
        // frame. Access locals thru VarEnv.
        auto varEnv = fp->getVarEnv();
        auto func = fp->func();
        for (int i = 0; i < nformals; i++) {
          auto const argname = func->localVarName(i);
          auto const tv = varEnv->lookup(argname);

          Variant val;
          if (tv != nullptr) { // the variable hasn't been unset
            val = withValues ? tvAsVariant(tv) : "";
          }

          if (withNames) {
            args.set(String(const_cast<StringData*>(argname)), val);
          } else {
            args.append(val);
          }
        }
      } else {
        for (int i = 0; i < nformals; i++) {
          Variant val = withValues ? tvAsVariant(frame_local(fp, i)) : "";

          if (withNames) {
            auto const argname = fp->func()->localVarName(i);
            args.set(String(const_cast<StringData*>(argname)), val);
          } else {
            args.append(val);
          }
        }
      }

      // Builtin extra args are not stored in varenv.
      if (UNLIKELY(mayUseVV) && nargs > nparams && fp->hasExtraArgs()) {
        for (int i = nparams; i < nargs; i++) {
          auto arg = fp->getExtraArg(i - nparams);
          args.append(tvAsVariant(arg));
        }
      }
      frame.set(s_args, args);
    }

    if (btArgs.m_withMetadata && !isReturning) {
      if (UNLIKELY(mayUseVV) && UNLIKELY(fp->hasVarEnv())) {
        auto tv = fp->getVarEnv()->lookup(s_86metadata.get());
        if (tv != nullptr && tv->m_type != KindOfUninit) {
          frame.set(s_metadata, tvAsVariant(tv));
        }
      } else {
        auto local = fp->func()->lookupVarId(s_86metadata.get());
        if (local != kInvalidId) {
          auto tv = frame_local(fp, local);
          if (tv->m_type != KindOfUninit) {
            frame.set(s_metadata, tvAsVariant(tv));
          }
        }
      }
    }

    bt.append(frame.toVariant());
    depth++;
  }

  return bt;
}