Args::Args(Pass1 *pass1, ParseNode *node) { assert(node->token == RULE_ARGS); std::list<ParseNode *>::iterator i = node->children.begin(); assert(i != node->children.end()); for(;;) { accept_arg(pass1, *i); ++i; // skip past arg if(i == node->children.end()) break; assert((*i)->token == ','); ++i; // skip comma assert(i != node->children.end()); } // For each parameterized type, make sure the type exists with a scalar of one someplace. // Also do some sanity checks. ///int argnum = 0; for(std::vector<Arg>::iterator j = args.begin(); j != args.end(); ++j) { ///++argnum; std::string arg_name = j->arg_name, size_name = j->size_name; if(j->base_size >= 0) size_name.clear(); if(!pass1->is_valid_new_ident(arg_name)) { throw ParseError(std::string("Argument name in use already: ") + j->arg_name, node->lineNum, node->fileNum, __LINE__ ); } // Make sure no other arguments have the same name, and make sure our type name is valid. if(!size_name.empty()) { if(!pass1->is_valid_new_ident(size_name)) { ///std::cout << argnum << "[" << j->base_size << "]"; throw ParseError(std::string("Argument size in use already: ") + size_name, node->lineNum, node->fileNum, __LINE__ ); } } for(std::vector<Arg>::iterator k = args.begin(); k != args.end(); ++k) { if(k != j) { if(k->arg_name == arg_name) { throw ParseError(std::string("Argument name repeated: ") + arg_name, node->lineNum, node->fileNum, __LINE__ ); } if(!size_name.empty()) { if(k->arg_name == size_name) { throw ParseError(std::string("Argument name is same as a size name: ") + k->arg_name, node->lineNum, node->fileNum, __LINE__ ); } } } } if(j->base_size == -1 && j->scalar != 1) { std::vector<Arg>::iterator k = args.begin(); for(; k != args.end(); ++k) { if(k->base_size == -1) { if(k->size_name == j->size_name && k->scalar == 1) break; } } if(k == args.end()) { throw ParseError(std::string("Parameterized argument is scaled; can't find unscaled argument: ") + j->arg_name, node->lineNum, node->fileNum, __LINE__ ); } } } // fn/insn ( P * 2 x, P y ); // Now create arguments in Pass1 object. short num_arg_types = -1; short arg_count = 0; for(std::vector<Arg>::iterator j = args.begin(); j != args.end(); ++j) { if(j->base_size == -1) { // Parameterized argument. std::map<std::string, short>::iterator k = argtypes.find(j->size_name); if(k == argtypes.end()) { // Create arg type. argtypes[j->size_name] = num_arg_types; assert(pass1->is_valid_new_ident(j->size_name)); Size size(num_arg_types, 1); pass1->addsym(j->size_name, new Symbol(ST_ARGSIZE, num_arg_types, size)); pass1->locals.insert(j->size_name); --num_arg_types; } } // Make sure argument is not already taken. assert(pass1->is_valid_new_ident(j->arg_name)); short sz = j->base_size; if(sz == -1) sz = argtypes[j->size_name]; Size size(sz, j->scalar); pass1->addsym(j->arg_name, new Symbol(ST_ARGNAME, arg_count, size)); pass1->locals.insert(j->arg_name); ++arg_count; } }
// Primarily our action depends on incoming message type, but // drop all normal requests (execute, replicate, accept) during view // change void paxserver::dispatch(paxmsg_t &paxmsg) { net->rpc_incr(paxmsg.rpc_id); // Set basis for timeout if(paxmsg.rpc_id != execute_arg::ID) { if(paxmsg.sent_tick > recent_recv[paxmsg.src]) { // Note that I rely on reasonably synchronized clocks here, by checking // a tick count done on a different machine recent_recv[paxmsg.src] = paxmsg.sent_tick; } } if(vc_state.mode != vc_state_t::ACTIVE && is_normal_msg(paxmsg.rpc_id)) { net->drop(this, paxmsg, "not ACTIVE"); return; } switch(paxmsg.rpc_id) { case nop_msg::ID: break; case execute_arg::ID: execute_arg(static_cast<const struct execute_arg&>(paxmsg)); break; case replicate_arg::ID: replicate_arg(static_cast<const struct replicate_arg&>(paxmsg)); break; case replicate_res::ID: replicate_res(static_cast<const struct replicate_res&>(paxmsg)); break; case accept_arg::ID : accept_arg(static_cast<const struct accept_arg&>(paxmsg)); break; case view_change_arg::ID: view_change_arg(static_cast<const struct view_change_arg&>(paxmsg)); break; case view_change_reject::ID: view_change_reject( static_cast<const struct view_change_reject&>(paxmsg)); break; case view_change_accept::ID: view_change_accept( static_cast<const struct view_change_accept&>(paxmsg)); break; case new_view_arg::ID: new_view_arg(static_cast<const struct new_view_arg&>(paxmsg)); break; case new_view_res::ID: new_view_res(static_cast<const struct new_view_res&>(paxmsg)); break; case init_view_request::ID: init_view_request( static_cast<const struct init_view_request&>(paxmsg)); break; case init_view_arg::ID: init_view_arg(static_cast<const struct init_view_arg&>(paxmsg)); break; case getstate_arg::ID: getstate_arg(static_cast<const struct getstate_arg&>(paxmsg)); break; case getstate_res::ID: getstate_res(static_cast<struct getstate_res&>(paxmsg)); break; default: MASSERT(0, "%s %d Should be a handler for each RPC", id_str(), paxmsg.rpc_id); } }