Example #1
0
/*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);

}
Example #2
0
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;
}
Example #3
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?
}
Example #4
0
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;
}
Example #5
0
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
}
Example #7
0
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?
}
Example #8
0
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);

}
Example #9
0
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;
}
Example #10
0
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);
    }
}
Example #11
0
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(&current_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(&current_char));
	}
	else if (ch == '{'){
		ch = *(skip_comment(&current_char));
	}

	if (ch == '\n'){
		ch = get_char(&current_char);
	}
	
    if (char_table[ch] = DIGIT){
		token_string[0] = ch;
    	token -> literal_type = INTEGER_LIT;
    	token -> token_code = NUMBER;
    	get_number(&current_char, token_string, token_ptr);
    }
    else if (ch == '\''){
    	token -> literal_type = STRING_LIT;
    	token -> token_code = STRING;
    	get_string(&current_char,token_string, token_ptr);
    }
    else if (char_table[ch] = LETTER){
		token_string[0] = ch;
    	token -> literal_type = REAL_LIT;
		get_word(&current_char,token_string, token_ptr, token);
    }
    else if (char_table[ch] = SPECIAL){
    	token -> literal_type = REAL_LIT;
		token_string[0] = ch;
    	get_special(&current_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?
}
Example #13
0
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]);
  }

}
Example #14
0
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?
}
Example #15
0
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?
}
Example #16
0
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);
}
Example #17
0
/*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);
}
Example #18
0
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);

}
Example #19
0
/*
 * 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;
}