/*when a function is redefined, we need to know what PICs to flush. Here each method will keep a list of all the pics that it is in */ void method_pic_add_callee_backreference(struct object_heap* oh, struct CompiledMethod* caller, struct CompiledMethod* callee) { if (callee->base.map->delegates->elements[0] == oh->cached.closure_method_window) callee = callee->method; if (callee->base.map->delegates->elements[0] == oh->cached.primitive_method_window) return; assert (callee->base.map->delegates->elements[0] == oh->cached.compiled_method_window); if ((struct Object*)callee->cachedInCallers == oh->cached.nil) { callee->cachedInCallers = heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), 32); heap_store_into(oh, (struct Object*)callee, (struct Object*)callee->cachedInCallers); callee->cachedInCallersCount = smallint_to_object(0); } if (object_to_smallint(callee->cachedInCallersCount) >= array_size(callee->cachedInCallers)) { struct OopArray* newArray = heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), array_size(callee->cachedInCallers) * 2); copy_words_into(callee->cachedInCallers->elements, array_size(callee->cachedInCallers), newArray->elements); callee->cachedInCallers = newArray; heap_store_into(oh, (struct Object*)callee, (struct Object*)callee->cachedInCallers); } callee->cachedInCallers->elements[object_to_smallint(callee->cachedInCallersCount)] = (struct Object*)caller; heap_store_into(oh, (struct Object*)callee->cachedInCallers, (struct Object*)caller); callee->cachedInCallersCount = smallint_to_object(object_to_smallint(callee->cachedInCallersCount) + 1); }
int main(int argc, char *argv[]) { // A decorated affine form yalaa::aff_e_d_dec x0(iv_t(-1.0, 2.0)); // A new affine form has the best decoration, as long as its original interval // is not empty or invalid. std::cout << "Decoration of x0: " << get_special(x0) << std::endl; // Square x0 is D5 (= 6), the best decoration std::cout << x0 << "^2 = " << sqr(x0) << " Deco: " << get_special(sqr(x0)) << " Valid: " << is_valid(sqr(x0)) << std::endl; // The natural domain of sqrt is R+. Thus the resulting decoration of sqrt(x0) // is D2 (=3) (possibly defined) std::cout << "sqrt(" << x0 << ") = " << sqrt(x0) << " Deco: " << get_special(sqrt(x0)) << " Valid: " << is_valid(sqrt(x0)) << std::endl; // The natural domain of log is R+, Thus the decoration is D2, as for lim x->0 log(x) is unbounded // the computation overflows for the natural domain resulting in Infinity as central value // Note the changed value of valid. Even if the decoration quality is the some as for sqrt(x0), // is_valid returns now false, as the form has no numerical meaningful value anymore. std::cout << "log(" << x0 << ") = " << log(x0) << " Deco: " << get_special(log(x0)) << " Valid: " << is_valid(log(x0)) << std::endl; // A form for an empty interval is created. The decoration is D0 (=1). yalaa::aff_e_d_dec empty(iv_t(1, -1)); std::cout << "Decoration of an empty affine form: " << get_special(empty) << " Valid: " << is_valid(empty) << std::endl; // If the empty is used as input argument of an operation, the result is again D0 std::cout << "cos(" << empty << ") = " << cos(empty) << " Deco: " << get_special(cos(empty)) << " Valid: " << is_valid(cos(empty)) << std::endl; // Combination of an affine form with a scalar // Normally scalars are treated like affine forms with a D5 decoration. However, if they have a // special value like NaN or infinity, the combination results in D-1 (=0) with indicates some // error. std::cout << "3.0*" << x0 << ") = " << 3*x0 << " Deco: " << get_special(3*x0) << " Valid: " << is_valid(3*x0) << std::endl; std::cout << "infinity*" << x0 << ") = " << std::numeric_limits<double>::infinity()*x0 << " Deco: " << get_special(std::numeric_limits<double>::infinity()*x0) << " Valid: " << is_valid(std::numeric_limits<double>::infinity()*x0) << std::endl; // Decoations are propagated through inductively defined functions // Thus f = sqrt(x0) + x0 // has the decoration D2, as sqrt(x0) is D2. yalaa::aff_e_d_dec sqrtx0(sqrt(x0)); std::cout << "sqrt(" << x0 << ") + " << x0 << " = " << sqrt(x0) + x0 << " Deco: " << get_special(sqrt(x0) + x0) << " Valid: " << is_valid(sqrt(x0) + x0) << std::endl; // The natural domain of exp is not violated, but the computation overflows resulting in D4 // (defined and continuous). No statement is made about the boundness! // Commented out, as some libraries like C-XSC abort the program in case of an overflow. // yalaa::aff_e_d_dec x1(1000.0); // std::cout << "exp(" << x1 << ") = " << exp(x1) << " Deco: " << get_special(exp(x1)) << std::endl; return 0; }
Token* get_token(char *stringtotoken) { char source_buffer[MAX_TOKEN_STRING_LENGTH]; char ch = source_buffer[0]; //This can be the current character you are examining during scanning. int chint = (int)ch; char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. //if(sourceline[0]=='\n'); //{get_source_line(source_buffer);} //struct stack * newptr=(struct stack*)malloc(sizeof(struct stack)); struct Token * token1 = (struct Token*)malloc(sizeof(Token)); //???; //I am missing the most important variable in the function, what is it? Hint: what should I return? //2. figure out which case you are dealing with LETTER, DIGIT, QUOTE, EOF, or special, by examining ch if (isdigit(chint)) { if (isalpha(chint)) { token1 =get_word(source_buffer,token1); } else { if (chint == 39) token1 = get_string(source_buffer,token1); } token1 = get_number(source_buffer,token1); } else token1 = get_special(source_buffer,token1); //3. Call the appropriate function to deal with the cases in 2. strcpy(sourceLine,source_buffer); return token1; //What should be returned here? }
struct Token* get_token() { struct Token newToken; struct Token* retToken; char c = '\0'; retToken = (struct Token*)malloc(sizeof(struct Token)); c = skip_blanks(); if(peek_char() == '{') { c = skip_comment(); } if(char_table[c] == LETTER) { newToken = get_word(c); } else if(char_table[c] == DIGIT) { newToken = get_number(c); } else if(char_table[c] == QUOTE) { newToken = get_string(c); } else if(c == EOF) { newToken.literalValue.valString[0] = '.'; newToken.literalType = INTEGER_LIT; newToken.tokenCode = END_OF_FILE; } else if(char_table[c] == SPECIAL) { newToken = get_special(c); } memcpy(retToken, &newToken, sizeof(struct Token)); return retToken; }
struct MethodDefinition* method_define(struct object_heap* oh, struct Object* method, struct Symbol* selector, struct Object* args[], word_t n) { word_t positions, i; struct Object* argBuffer[MAX_ARITY]; Pinned<struct MethodDefinition> def(oh); Pinned<struct MethodDefinition> oldDef(oh); def = (struct MethodDefinition*)heap_clone_special(oh, SPECIAL_OOP_METHOD_DEF_PROTO); positions = 0; for (i = 0; i < n; i++) { if (!object_is_smallint(args[i]) && args[i] != get_special(oh, SPECIAL_OOP_NO_ROLE)) { positions |= (1 << i); } } /* any methods that call the same symbol must be decompiled because they might call an old version */ method_remove_optimized_sending(oh, selector); selector->cacheMask = smallint_to_object(object_to_smallint(selector->cacheMask) | positions); assert(n <= MAX_ARITY); copy_words_into(args, n, argBuffer); /* method_dispatch_on modifies its arguments (first argument)*/ oldDef = method_dispatch_on(oh, selector, argBuffer, n, NULL); if (oldDef == (struct Object*)NULL || oldDef->dispatchPositions != positions || oldDef != method_is_on_arity(oh, oldDef->method, selector, args, n)) { oldDef = NULL; } if (oldDef != (struct Object*)NULL) { Pinned<struct CompiledMethod> oldDefMethod(oh); oldDefMethod = (struct CompiledMethod*)oldDef->method; method_pic_flush_caller_pics(oh, (struct CompiledMethod*)oldDefMethod); } def->method = method; heap_store_into(oh, (struct Object*) def, (struct Object*) method); def->dispatchPositions = positions; for (i = 0; i < n; i++) { if (!object_is_smallint(args[i]) && (struct Object*)args[i] != get_special(oh, SPECIAL_OOP_NO_ROLE)) { if (oldDef != (struct Object*)NULL) { object_remove_role(oh, args[i], selector, oldDef); } object_add_role_at(oh, args[i], selector, 1<<i, def); } } return def; }
/*this code is useful if you want to see how to make a primitive to return nested arrays*/ struct Object* dir_contents(struct object_heap* oh, char* dirpath) { #ifdef WIN32 return FALSE; /*fixme*/ #else DIR* dir; int count, i; word_t lenfilename; struct dirent* direntry; struct OopArray* array; dir = opendir(dirpath); if (dir == NULL) { return oh->cached.nil; } /*get a count of the number of entries but we can't trust this*/ count = 0; while ((direntry = readdir(dir))) count++; rewinddir(dir); i = 0; array = heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), count); heap_fixed_add(oh, (struct Object*)array); while ((direntry = readdir(dir)) && i < count) { array->elements[i] = (struct Object*) heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), 2); heap_store_into(oh, (struct Object*)array, (struct Object*)array->elements[i]); ((struct OopArray*)array->elements[i])->elements[0] = smallint_to_object(slate_direntry_type(direntry->d_type)); heap_store_into(oh, (struct Object*)array->elements[i], (struct Object*)((struct OopArray*)array->elements[i])->elements[1]); lenfilename = strlen(direntry->d_name); ((struct OopArray*)array->elements[i])->elements[1] = (struct Object*) heap_clone_byte_array_sized(oh, get_special(oh, SPECIAL_OOP_BYTE_ARRAY_PROTO), lenfilename); copy_bytes_into((byte_t*)direntry->d_name, lenfilename, ((struct ByteArray*)((struct OopArray*)array->elements[i])->elements[1])->elements); i++; } closedir(dir); heap_fixed_remove(oh, (struct Object*)array); return (struct Object*)array; #endif }
char get_token() { // char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. get_source_line(token_string); while(token_string[0] != '\0') { //printf("I went through the while loop: %d times\n", debugCount); //debug line transfer(skipArray,token_string); skip_blanks(skipArray); //1. Skip past all of the blanks transfer(token_string,skipArray); //printf("This is token_string after skip_blanks :2%s2\n", token_string); //debug //printf("ldksaf"); if(token_string[0] == '\n') { return 'a'; } if(token_string[0] == '.') { printf("\t>> .\t.\n"); return '.'; } if(isalpha(token_string[0])) { get_word(); } else if(isdigit(token_string[0])) { //token_string = get_number(token_string); get_number(); } else if(token_string[0] == '\'') { //token_string = get_string(token_string); get_string(); } else if(token_string[0] == '{'){ skip_comment(token_string); } else { if(token_string[0] == '.') { return '.'; } get_special(); } } return 'a'; //What should be returned here? }
void cache_specials(struct object_heap* heap) { heap->cached.interpreter = (struct Interpreter*) get_special(heap, SPECIAL_OOP_INTERPRETER); heap->cached.true_object = (struct Object*) get_special(heap, SPECIAL_OOP_TRUE); heap->cached.false_object = (struct Object*) get_special(heap, SPECIAL_OOP_FALSE); heap->cached.nil = (struct Object*) get_special(heap, SPECIAL_OOP_NIL); heap->cached.primitive_method_window = (struct Object*) get_special(heap, SPECIAL_OOP_PRIMITIVE_METHOD_WINDOW); heap->cached.compiled_method_window = (struct Object*) get_special(heap, SPECIAL_OOP_COMPILED_METHOD_WINDOW); heap->cached.closure_method_window = (struct Object*) get_special(heap, SPECIAL_OOP_CLOSURE_WINDOW); }
Token * get_token() { char ch; /*/This can be the current character you are examining during scanning. */ char token_string[MAX_TOKEN_STRING_LENGTH]; /*Store your token here as you build it. */ Token *token2 = malloc(sizeof(Token)); ch = get_char(token_string); char comp = '\''; /*/1. Skip past all of the blanks */ /*/2. figure out which case you are dealing with LETTER, DIGIT, QUOTE, EOF, or special, by examining ch */ /*/decides to get_word()(if it is a letter), get_number()(if it is a number), get_string()(if it is a quote ‘), if it is the end of the file, */ /*/or else it must have a special so it can get_special(). */ /*/ isalpha does not work with lower case */ if (isalpha(ch)!=0) { token2 = get_word(token_string, token2); /*/(if it is a LETTER) */ } else if (isdigit(ch) ) { token2 = get_number(token_string, token2); /*/(if it is a DIGIT) */ } else if (ch == comp) { token2 = get_string(token_string, token2); /*/(if it is a quote ‘) */ } else if (ch == EOF) { return NULL; } else if (ch == '\n') { token2->type = STRING_LIT; token2->nextptr = NULL; strcpy(token2->token_string, " "); /*/copy source_buffer into tmp_buffer */ token2->code = NO_TOKEN; } else { token2 = get_special(token_string, token2); /*/ Special character */ } return token2; }
Json_Token JSON::Lexer::get_token() { unsigned int c = peek_byte(); while (isspace(c)) { next_byte(); c = peek_byte(); } switch (c) { case ':': next_byte(); return Colon_token; case ',': next_byte(); return Comma_token; case '{': next_byte(); return Object_start_token; case '}': next_byte(); return Object_stop_token; case '[': next_byte(); return Array_start_token; case ']': next_byte(); return Array_stop_token; case '"': return get_string(); case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return get_number(c); default: return get_special(c); } }
static int get_variable(SEXP variable, struct design *s, struct design *r, struct design2 *d, struct variable *v) { int err = 0; if (isMatrix(variable) || inherits(variable, "matrix")) { err = get_trait(variable, s, r, v); } else if (inherits(variable, "special")) { err = get_special(variable, s, r, d, v); } else { DOMAIN_ERROR("unknown variable type"); } return err; }
Token* get_token() { char ch; //This can be the current character you are examining during scanning. static char* current_char = src_name; //This is the pointer to the current character being read char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. char *token_ptr = token_string; //write some code to point this to the beginning of token_string Token* token = (Token *) malloc(sizeof(Token)); //I am missing the most important variable in the function, what is it? Hint: what should I return? ch = get_char(¤t_char); //1. Skip past all of the blanks //2. figure out which case you are dealing with LETTER, DIGIT, QUOTE, EOF, or special, by examining ch //3. Call the appropriate function to deal with the cases in 2. if (ch == ' '){ ch = *(skip_blanks(¤t_char)); } else if (ch == '{'){ ch = *(skip_comment(¤t_char)); } if (ch == '\n'){ ch = get_char(¤t_char); } if (char_table[ch] = DIGIT){ token_string[0] = ch; token -> literal_type = INTEGER_LIT; token -> token_code = NUMBER; get_number(¤t_char, token_string, token_ptr); } else if (ch == '\''){ token -> literal_type = STRING_LIT; token -> token_code = STRING; get_string(¤t_char,token_string, token_ptr); } else if (char_table[ch] = LETTER){ token_string[0] = ch; token -> literal_type = REAL_LIT; get_word(¤t_char,token_string, token_ptr, token); } else if (char_table[ch] = SPECIAL){ token -> literal_type = REAL_LIT; token_string[0] = ch; get_special(¤t_char,token_string, token_ptr, token); } token -> content = (char *) malloc(sizeof(char) * strlen(token_string)); strcpy(token -> content, token_string); return token; //What should be returned here? }
void method_pic_insert(struct object_heap* oh, struct OopArray* calleeCount, struct Object* picEntry[], struct MethodDefinition* def, word_t arity, struct Object* args[]) { word_t j; picEntry[PIC_CALLEE] = (struct Object*)def; picEntry[PIC_CALLEE_ARITY] = smallint_to_object(arity); picEntry[PIC_CALLEE_COUNT] = smallint_to_object(1); picEntry[PIC_CALLEE_MAPS] = (struct Object*)heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), arity); heap_store_into(oh, (struct Object*) calleeCount, picEntry[PIC_CALLEE]); heap_store_into(oh, (struct Object*) calleeCount, picEntry[PIC_CALLEE_MAPS]); for (j = 0; j < arity; j++) { ((struct OopArray*)picEntry[PIC_CALLEE_MAPS])->elements[j] = (struct Object*)object_get_map(oh, args[j]); heap_store_into(oh, picEntry[PIC_CALLEE_MAPS], ((struct OopArray*)picEntry[PIC_CALLEE_MAPS])->elements[j]); } }
Token* get_token() { char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. static char source_buffer[MAX_SOURCE_LINE_LENGTH] = {NULL}; Token *theToken = (struct Token*)malloc(sizeof(Token));//I am missing the most important variable in the function, what is it? Hint: what should I return? static char *token_ptr; token_ptr = get_char(source_buffer,token_ptr); switch(char_table[*(token_ptr)]) { case LETTER: token_ptr = get_word(theToken,token_string,token_ptr); break; case DIGIT: token_ptr = get_number(theToken,token_string,token_ptr); break; case QUOTE: token_ptr = get_string(theToken,token_string,token_ptr); break; case SPECIAL: token_ptr = get_special(theToken,token_string,token_ptr); break; case END_OF_FILE: theToken->token_code = PERIOD; theToken->literal_value = "."; theToken->nextToken = NULL; break; default: theToken->token_code = PERIOD; theToken->literal_value = "."; theToken->nextToken = NULL; break; } //2. figure out which case you are dealing with LETTER, DIGIT, QUOTE, EOF, or special, by examining ch //3. Call the appropriate function to deal with the cases in 2. return theToken; //What should be returned here? }
Token* get_token() { char ch; //This can be the current character you are examining during scanning. static char token_string[MAX_TOKEN_STRING_LENGTH]; //Store your token here as you build it. char *token_ptr = token_string; //write some code to point this to the beginning of token_string int loop = FALSE; int symbol_code; Token* token = (Token*)malloc(sizeof(Token)); //allocate memory for struct CharCode code; //get_char will set global ptr src_ptr to the source_buffer line //get_char will also set ch to the first character in source_buffer, if the end of line has been reached, //otherwise will set ch to what GLOBAL src_ptr is currently looking at. //other methods will set ch to the next char in the source_buffer after they have tokenized token->next = NULL; get_char(token_string); ch = *src_ptr; //if get_char shows us that we have a blank space or the beginning of a comment we need to skip over all spaces and comments //until we come to a token if(ch == ' ' || ch == '\n' || ch == '{' || ch == '\r' || ch == '\t') { loop = TRUE; // Execute the loop for skipping spaces, skipping comments, and getting a new line } while(loop) { //check to see what the current ch is if(ch == ' ' || ch == '\t') { //call function skip_blanks which returns a pointer to the first non-blank character // if it reaches null terminator it will set ch to '\0' and come back here skip_blanks(&ch); //now call get_char again to get a new line if ch is a null terminator if(ch == '\n' || ch == '\r') { //call get_char to get a new source line get_char(token_string); ch = *src_ptr; } //after this there may be more spaces or comments, need to continue to evaluae loop loop = TRUE; } //now check to see if there is a comment and skip over this as well else if(ch == '{') { loop = TRUE; //skip_comment will return the character following the ending bracket //src_ptr will also be pointing here //ch will contin current value of src_ptr skip_comment(&ch, token_string); } else if(ch == '\n' || ch == '\r') { get_char(token_string); ch = *src_ptr; loop = TRUE; } else { //if no matches then we are looking at a valid character loop = FALSE; //make sure to update ch to what src_ptr is looking at ch = *src_ptr; } } //position 'ch' in char_table will return a CharCode corresponding to Letter, Digit, Quote, etc... code = char_table[ch]; //check to see if code for ch is a LETTER if(code == LETTER) { //pass in the token_string array to point to, and the current Token struct. //get_word will set the tokens values appropriately so it can be returned //to main get_word( token); } //check to see if it is a digit else if(code == DIGIT) { get_number(token); //The parameter has to be same as get_word because we need to build a character array to be converted to integers or real numbers } //check to see if it is a quote else if(code == QUOTE) { get_string(token); } else { //in the get_special function the token code will be set symbol_code = get_special(); //set token code to the symbol code token->code = (TokenCode)symbol_code; //the literal type for the token will be a str_lit and the char ptr will point to the token_string array where //the characters are stored token->literal.str_lit = token_string; //type of token will be set to string_lit token->type = STRING_LIT; } //3. Call the appropriate function to deal with the cases in 2. return token; //What should be returned here? }
error_t cvt_to_hyper(menu_t *mp, char *osroot, char *extra_args) { const char *fcn = "cvt_to_hyper()"; line_t *lp; entry_t *ent; size_t len, zfslen; char *newstr; char *osdev; char *title = NULL; char *findroot = NULL; char *bootfs = NULL; char *kernel = NULL; char *mod_kernel = NULL; char *module = NULL; char *kern_path = NULL; char *kern_bargs = NULL; int curdef, newdef; int kp_allocated = 0; int ret = BAM_ERROR; assert(osroot); BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, extra_args)); /* * First just check to verify osroot is a sane directory. */ if ((osdev = get_special(osroot)) == NULL) { bam_error(CANT_FIND_SPECIAL, osroot); return (BAM_ERROR); } free(osdev); /* * While the effect is purely cosmetic, if osroot is "/" don't * bother prepending it to any paths as they are constructed to * begin with "/" anyway. */ if (strcmp(osroot, "/") == 0) osroot = ""; /* * Found the GRUB signature on the target partitions, so now get the * default GRUB boot entry number from the menu.lst file */ curdef = atoi(mp->curdefault->arg); /* look for the first line of the matching boot entry */ for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef)); ent = ent->next) ; /* couldn't find it, so error out */ if (ent == NULL) { bam_error(CANT_FIND_DEFAULT, curdef); goto abort; } /* * We found the proper menu entry, so first we need to process the * bootenv.rc file to look for boot options the hypervisor might need * passed as kernel start options such as the console device and serial * port parameters. * * If there's no bootenv.rc, it's not an issue. */ parse_bootenvrc(osroot); if (bootenv_rc_console != NULL) console_metal_to_hyper(bootenv_rc_console); if (bootenv_rc_serial[0] != NULL) (void) serial_metal_to_hyper("ttya-mode", bootenv_rc_serial[0]); if (bootenv_rc_serial[1] != NULL) (void) serial_metal_to_hyper("ttyb-mode", bootenv_rc_serial[1]); /* * Now process the entry itself. */ for (lp = ent->start; lp != NULL; lp = lp->next) { /* * Process important lines from menu.lst boot entry. */ if (lp->flags == BAM_TITLE) { title = alloca(strlen(lp->arg) + 1); (void) strcpy(title, lp->arg); } else if (strcmp(lp->cmd, "findroot") == 0) { findroot = alloca(strlen(lp->arg) + 1); (void) strcpy(findroot, lp->arg); } else if (strcmp(lp->cmd, "bootfs") == 0) { bootfs = alloca(strlen(lp->arg) + 1); (void) strcpy(bootfs, lp->arg); } else if (strcmp(lp->cmd, menu_cmds[MODULE_DOLLAR_CMD]) == 0) { module = alloca(strlen(lp->arg) + 1); (void) strcpy(module, lp->arg); } else if ((strcmp(lp->cmd, menu_cmds[KERNEL_DOLLAR_CMD]) == 0) && (ret = cvt_metal_kernel(lp->arg, &kern_path)) != 0) { if (ret < 0) { ret = BAM_ERROR; bam_error(KERNEL_NOT_PARSEABLE, curdef); } else ret = BAM_NOCHANGE; goto abort; } if (lp == ent->end) break; } /* * If findroot, module or kern_path are NULL, the boot entry is * malformed. */ if (findroot == NULL) { bam_error(FINDROOT_NOT_FOUND, curdef); goto abort; } if (module == NULL) { bam_error(MODULE_NOT_PARSEABLE, curdef); goto abort; } if (kern_path == NULL) { bam_error(KERNEL_NOT_FOUND, curdef); goto abort; } /* assemble new kernel and module arguments from parsed values */ if (console_dev != NULL) { kern_bargs = s_strdup(console_dev); if (serial_config[0] != NULL) { newstr = append_str(kern_bargs, serial_config[0], " "); free(kern_bargs); kern_bargs = newstr; } if (serial_config[1] != NULL) { newstr = append_str(kern_bargs, serial_config[1], " "); free(kern_bargs); kern_bargs = newstr; } } if ((extra_args != NULL) && (*extra_args != NULL)) { newstr = append_str(kern_bargs, extra_args, " "); free(kern_bargs); kern_bargs = newstr; } len = strlen(osroot) + strlen(XEN_MENU) + strlen(kern_bargs) + WHITESPC(1) + 1; kernel = alloca(len); if (kern_bargs != NULL) { if (*kern_bargs != NULL) (void) snprintf(kernel, len, "%s%s %s", osroot, XEN_MENU, kern_bargs); free(kern_bargs); } else { (void) snprintf(kernel, len, "%s%s", osroot, XEN_MENU); } /* * Change the kernel directory from the metal version to that needed for * the hypervisor. Convert either "direct boot" path to the default * path. */ if ((strcmp(kern_path, DIRECT_BOOT_32) == 0) || (strcmp(kern_path, DIRECT_BOOT_64) == 0)) { kern_path = HYPERVISOR_KERNEL; } else { newstr = modify_path(kern_path, METAL_KERNEL_DIR, HYPER_KERNEL_DIR); free(kern_path); kern_path = newstr; kp_allocated = 1; } /* * We need to allocate space for the kernel path (twice) plus an * intervening space, possibly the ZFS boot string, and NULL, * of course. */ len = (strlen(kern_path) * 2) + WHITESPC(1) + 1; zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0); mod_kernel = alloca(len + zfslen); (void) snprintf(mod_kernel, len, "%s %s", kern_path, kern_path); if (kp_allocated) free(kern_path); if (zfs_boot) { char *zfsstr = alloca(zfslen + 1); (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT); (void) strcat(mod_kernel, zfsstr); } /* shut off warning messages from the entry line parser */ if (ent->flags & BAM_ENTRY_BOOTADM) ent->flags &= ~BAM_ENTRY_BOOTADM; BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel)); BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, mod_kernel)); if ((newdef = add_boot_entry(mp, title, findroot, kernel, mod_kernel, module, bootfs)) == BAM_ERROR) return (newdef); /* * Now try to delete the current default entry from the menu and add * the new hypervisor entry with the parameters we've setup. */ if (delete_boot_entry(mp, curdef, DBE_QUIET) == BAM_SUCCESS) newdef--; else bam_print(NEW_BOOT_ENTRY, title); /* * If we successfully created the new entry, set the default boot * entry to that entry and let the caller know the new menu should * be written out. */ return (set_global(mp, menu_cmds[DEFAULT_CMD], newdef)); abort: if (ret != BAM_NOCHANGE) bam_error(HYPER_ABORT, ((*osroot == NULL) ? "/" : osroot)); return (ret); }
/*ARGSUSED*/ error_t cvt_to_metal(menu_t *mp, char *osroot, char *menu_root) { const char *fcn = "cvt_to_metal()"; line_t *lp; entry_t *ent; size_t len, zfslen; char *delim = ","; char *newstr; char *osdev; char *title = NULL; char *findroot = NULL; char *bootfs = NULL; char *kernel = NULL; char *module = NULL; char *barchive_path = DIRECT_BOOT_ARCHIVE; char *kern_path = NULL; int curdef, newdef; int emit_bflag = 1; int ret = BAM_ERROR; assert(osroot); BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, "")); /* * First just check to verify osroot is a sane directory. */ if ((osdev = get_special(osroot)) == NULL) { bam_error(CANT_FIND_SPECIAL, osroot); return (BAM_ERROR); } free(osdev); /* * Found the GRUB signature on the target partitions, so now get the * default GRUB boot entry number from the menu.lst file */ curdef = atoi(mp->curdefault->arg); /* look for the first line of the matching boot entry */ for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef)); ent = ent->next) ; /* couldn't find it, so error out */ if (ent == NULL) { bam_error(CANT_FIND_DEFAULT, curdef); goto abort; } /* * Now process the entry itself. */ for (lp = ent->start; lp != NULL; lp = lp->next) { /* * Process important lines from menu.lst boot entry. */ if (lp->flags == BAM_TITLE) { title = alloca(strlen(lp->arg) + 1); (void) strcpy(title, lp->arg); } else if (strcmp(lp->cmd, "findroot") == 0) { findroot = alloca(strlen(lp->arg) + 1); (void) strcpy(findroot, lp->arg); } else if (strcmp(lp->cmd, "bootfs") == 0) { bootfs = alloca(strlen(lp->arg) + 1); (void) strcpy(bootfs, lp->arg); } else if (strcmp(lp->cmd, menu_cmds[MODULE_DOLLAR_CMD]) == 0) { if (strstr(lp->arg, "boot_archive") == NULL) { module = alloca(strlen(lp->arg) + 1); (void) strcpy(module, lp->arg); cvt_hyper_module(module, &kern_path); } else { barchive_path = alloca(strlen(lp->arg) + 1); (void) strcpy(barchive_path, lp->arg); } } else if ((strcmp(lp->cmd, menu_cmds[KERNEL_DOLLAR_CMD]) == 0) && (cvt_hyper_kernel(lp->arg) < 0)) { ret = BAM_NOCHANGE; goto abort; } if (lp == ent->end) break; } /* * If findroot, module or kern_path are NULL, the boot entry is * malformed. */ if (findroot == NULL) { bam_error(FINDROOT_NOT_FOUND, curdef); goto abort; } if (module == NULL) { bam_error(MODULE_NOT_PARSEABLE, curdef); goto abort; } if (kern_path == NULL) { bam_error(KERNEL_NOT_FOUND, curdef); goto abort; } /* * Assemble new kernel and module arguments from parsed values. * * First, change the kernel directory from the hypervisor version to * that needed for a metal kernel. */ newstr = modify_path(kern_path, HYPER_KERNEL_DIR, METAL_KERNEL_DIR); free(kern_path); kern_path = newstr; /* allocate initial space for the kernel path */ len = strlen(kern_path) + 1; zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0); if ((kernel = malloc(len + zfslen)) == NULL) { free(kern_path); bam_error(NO_MEM, len + zfslen); bam_exit(1); } (void) snprintf(kernel, len, "%s", kern_path); free(kern_path); if (zfs_boot) { char *zfsstr = alloca(zfslen + 1); (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT); (void) strcat(kernel, zfsstr); emit_bflag = 0; } /* * Process the bootenv.rc file to look for boot options that would be * the same as what the hypervisor had manually set, as we need not set * those explicitly. * * If there's no bootenv.rc, it's not an issue. */ parse_bootenvrc(osroot); /* * Don't emit a console setting if it's the same as what would be * set by bootenv.rc. */ if ((console_dev != NULL) && (bootenv_rc_console == NULL || (strcmp(console_dev, bootenv_rc_console) != 0))) { if (emit_bflag) { newstr = append_str(kernel, BFLAG, " "); free(kernel); kernel = append_str(newstr, "console=", " "); free(newstr); newstr = append_str(kernel, console_dev, ""); free(kernel); kernel = newstr; emit_bflag = 0; } else { newstr = append_str(kernel, "console=", ","); free(kernel); kernel = append_str(newstr, console_dev, ""); free(newstr); } } /* * We have to do some strange processing here because the hypervisor's * serial ports default to "9600,8,n,1,-" if "comX=auto" is specified, * or to "auto" if nothing is specified. * * This could result in a serial mode setting string being added when * it would otherwise not be needed, but it's better to play it safe. */ if (emit_bflag) { newstr = append_str(kernel, BFLAG, " "); free(kernel); kernel = newstr; delim = " "; emit_bflag = 0; } if ((serial_config[0] != NULL) && (bootenv_rc_serial[0] == NULL || (strcmp(serial_config[0], bootenv_rc_serial[0]) != 0))) { newstr = append_str(kernel, "ttya-mode='", delim); free(kernel); /* * Pass the serial configuration as the delimiter to * append_str() as it will be inserted between the current * string and the string we're appending, in this case the * closing single quote. */ kernel = append_str(newstr, "'", serial_config[0]); free(newstr); delim = ","; } if ((serial_config[1] != NULL) && (bootenv_rc_serial[1] == NULL || (strcmp(serial_config[1], bootenv_rc_serial[1]) != 0))) { newstr = append_str(kernel, "ttyb-mode='", delim); free(kernel); /* * Pass the serial configuration as the delimiter to * append_str() as it will be inserted between the current * string and the string we're appending, in this case the * closing single quote. */ kernel = append_str(newstr, "'", serial_config[1]); free(newstr); delim = ","; } /* shut off warning messages from the entry line parser */ if (ent->flags & BAM_ENTRY_BOOTADM) ent->flags &= ~BAM_ENTRY_BOOTADM; BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel)); BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, module)); if ((newdef = add_boot_entry(mp, title, findroot, kernel, NULL, barchive_path, bootfs)) == BAM_ERROR) { free(kernel); return (newdef); } /* * Now try to delete the current default entry from the menu and add * the new hypervisor entry with the parameters we've setup. */ if (delete_boot_entry(mp, curdef, DBE_QUIET) == BAM_SUCCESS) newdef--; else bam_print(NEW_BOOT_ENTRY, title); free(kernel); /* * If we successfully created the new entry, set the default boot * entry to that entry and let the caller know the new menu should * be written out. */ return (set_global(mp, menu_cmds[DEFAULT_CMD], newdef)); abort: if (ret != BAM_NOCHANGE) bam_error(METAL_ABORT, osroot); return (ret); }
void method_pic_setup(struct object_heap* oh, struct CompiledMethod* caller) { caller->calleeCount = heap_clone_oop_array_sized(oh, get_special(oh, SPECIAL_OOP_ARRAY_PROTO), CALLER_PIC_SIZE*CALLER_PIC_ENTRY_SIZE); heap_store_into(oh, (struct Object*) caller, (struct Object*) caller->calleeCount); }
/* * This is the main dispatch function * */ struct MethodDefinition* method_dispatch_on(struct object_heap* oh, struct Symbol* name, struct Object* arguments[], word_t arity, struct Object* resendMethod) { struct MethodDefinition *dispatch, *bestDef; struct Object* slotLocation; word_t bestRank, depth, delegationCount, resendRank, restricted, i; #ifdef PRINT_DEBUG_DISPATCH fprintf(stderr, "dispatch to: '"); print_symbol(name); fprintf(stderr, "' (arity: %" PRIdPTR ")\n", arity); for (i = 0; i < arity; i++) { fprintf(stderr, "arguments[%" PRIdPTR "] (%p) = ", i, (void*)arguments[i]); print_type(oh, arguments[i]); } /* fprintf(stderr, "resend: "); print_object(resendMethod);*/ #endif dispatch = NULL; slotLocation = NULL; #ifndef SLATE_DISABLE_METHOD_CACHE if (resendMethod == NULL && arity <= METHOD_CACHE_ARITY) { dispatch = method_check_cache(oh, name, arguments, arity); if (dispatch != NULL) return dispatch; } #endif oh->current_dispatch_id++; bestRank = 0; bestDef = NULL; resendRank = ((resendMethod == NULL) ? WORDT_MAX : 0); for (i = 0; i < arity; i++) { struct Object *obj; struct Map* map; struct Object* arg = arguments[i]; delegationCount = 0; depth = 0; restricted = WORDT_MAX; /*pointer in delegate_stack (with sp of delegateCount) to where we don't trace further*/ do { /* Set up obj to be a pointer to the object, or SmallInteger if it's a direct SmallInt. */ if (object_is_smallint(arg)) { obj = get_special(oh, SPECIAL_OOP_SMALL_INT_PROTO); } else { obj = arg; } /* Identify the map, and update its dispatchID and reset the visited mask if it hasn't been visited during this call already. */ map = obj->map; if (map->dispatchID != oh->current_dispatch_id) { map->dispatchID = oh->current_dispatch_id; map->visitedPositions = 0; } /* we haven't been here before */ if ((map->visitedPositions & (1 << i)) == 0) { struct RoleEntry* role; /* If the map marks an obj-meta transition and the top of the stack is not the original argument, then mark the restriction point at the top of the delegation stack. */ if (((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION) && (arg != arguments[i])) { restricted = delegationCount; } map->visitedPositions |= (1 << i); role = role_table_entry_for_name(oh, map->roleTable, name); while (role != NULL) { if ((object_to_smallint(role->rolePositions) & (1 << i)) != 0) { struct MethodDefinition* def = role->methodDefinition; /* If the method hasn't been visited this time, mark it so and clear the other dispatch marks.*/ if (def->dispatchID != oh->current_dispatch_id) { def->dispatchID = oh->current_dispatch_id; def->foundPositions = 0; def->dispatchRank = 0; } /*If the method hasn't been found at this position...*/ if ((def->foundPositions & (1 << i)) == 0) { /*fix*/ def->dispatchRank |= ((31 - depth) << ((5 - i) * 5)); def->foundPositions |= (1 << i); #ifdef PRINT_DEBUG_FOUND_ROLE fprintf(stderr, "found role index %" PRIdPTR " <%p> for '%s' foundPos: %" PRIuPTR "x dispatchPos: %" PRIuPTR "x\n", i, (void*) role, ((struct Symbol*)(role->name))->elements, def->foundPositions, def->dispatchPositions); #endif if (def->method == resendMethod) { struct RoleEntry* rescan = role_table_entry_for_name(oh, map->roleTable, name); resendRank = def->dispatchRank; while (rescan != role) { struct MethodDefinition* redef = rescan->methodDefinition; if (redef->foundPositions == redef->dispatchPositions && (dispatch == NULL || redef->dispatchRank <= resendRank)) { dispatch = redef; slotLocation = obj; if (redef->dispatchRank > bestRank) { bestRank = redef->dispatchRank; bestDef = redef; } } if (rescan->nextRole == oh->cached.nil) { rescan = NULL; } else { rescan = &map->roleTable->roles[object_to_smallint(rescan->nextRole)]; } } } else /*not a resend*/ { if (def->foundPositions == def->dispatchPositions && (dispatch == NULL || def->dispatchRank > dispatch->dispatchRank) && def->dispatchRank <= resendRank) { dispatch = def; slotLocation = obj; if (def->dispatchRank > bestRank) { bestRank = def->dispatchRank; bestDef = def; } } } if (def->dispatchRank >= bestRank && def != bestDef) { bestRank = def->dispatchRank; bestDef = NULL; } } } role = ((role->nextRole == oh->cached.nil) ? NULL : &map->roleTable->roles[object_to_smallint(role->nextRole)]); } /*while role != NULL*/ if (depth > 31) { /*fix wordsize*/ assert(0); } if (dispatch != NULL && bestDef == dispatch) { if (dispatch->slotAccessor != oh->cached.nil) { arguments[0] = slotLocation; /*do we need to try to do a heap_store_into?*/ #ifdef PRINT_DEBUG_DISPATCH_SLOT_CHANGES fprintf(stderr, "arguments[0] changed to slot location: \n"); print_detail(oh, arguments[0]); #endif } if (resendMethod == 0 && arity <= METHOD_CACHE_ARITY) method_save_cache(oh, dispatch, name, arguments, arity); return dispatch; } depth++; /* We add the delegates to the list when we didn't just finish checking a restricted object*/ if (delegationCount <= restricted && array_size(map->delegates) > 0) { struct OopArray* delegates = map->delegates; word_t offset = object_array_offset((struct Object*)delegates); word_t limit = object_total_size((struct Object*)delegates); for (; offset != limit; offset += sizeof(word_t)) { struct Object* delegate = object_slot_value_at_offset((struct Object*)delegates, offset); if (delegate != oh->cached.nil) { oh->delegation_stack[delegationCount++] = delegate; } } } } /*end haven't been here before*/ delegationCount--; if (delegationCount < restricted) restricted = WORDT_MAX; /*everything is unrestricted now*/ if (delegationCount < 0 || delegationCount >= DELEGATION_STACK_SIZE) break; arg = oh->delegation_stack[delegationCount]; } while (1); } if (dispatch != NULL && dispatch->slotAccessor != oh->cached.nil) { /*check heap store into?*/ arguments[0] = slotLocation; #ifdef PRINT_DEBUG_DISPATCH_SLOT_CHANGES fprintf(stderr, "arguments[0] changed to slot location: \n"); print_detail(oh, arguments[0]); #endif } #ifndef SLATE_DISABLE_METHOD_CACHE if (dispatch != NULL && resendMethod == 0 && arity < METHOD_CACHE_ARITY) { method_save_cache(oh, dispatch, name, arguments, arity); } #endif return dispatch; }