Beispiel #1
0
  machine::machine(const string& file, const size_t th,
                   const scheduler_type _sched_type, const machine_arguments& margs, const string& data_file):
    filename(file),
    sched_type(_sched_type),
    alarm_thread(NULL),
    slices(th) /* th = number of threads, slices is for statistics */
  {
    bool added_data_file(false);

    vm::All = new vm::all();
    vm::All->PROGRAM = new vm::program(file);
    vm::theProgram = vm::All->PROGRAM;
    if(vm::All->PROGRAM->is_data())
      throw machine_error(string("cannot run data files"));
    if(data_file != string("")) {
      if(file_exists(data_file)) {
        vm::program data(data_file);
        if(!vm::All->PROGRAM->add_data_file(data)) {
          throw machine_error(string("could not import data file"));
        }
        added_data_file = true;
      } else {
        throw machine_error(string("data file ") + data_file + string(" not found"));
      }
    }

    if(margs.size() < vm::All->PROGRAM->num_args_needed())
      throw machine_error(string("this program requires ") + utils::to_string(vm::All->PROGRAM->num_args_needed()) + " arguments");

    vm::All->MACHINE = this;
    vm::All->ARGUMENTS = margs;
    vm::All->DATABASE = new database(added_data_file ? data_file : filename, get_creation_function(_sched_type));
    vm::All->NUM_THREADS = th;

    // Instantiate the scheduler object
    switch(sched_type) {
    case SCHED_SERIAL:
      vm::All->ALL_THREADS.push_back(dynamic_cast<sched::base*>(new sched::serial_local()));
      break;
    case SCHED_UNKNOWN: assert(false); break;
    default: break;
    }

    assert(vm::All->ALL_THREADS.size() == vm::All->NUM_THREADS);

  }
Beispiel #2
0
void exec_gfread(int oid, char* format){
    Odescr *specifier = pop_tstack();
    FILE *in_file = fopen(specifier->inst.sval, "r");
    if(in_file == NULL){
        machine_error("Could not open input file.");
    }
    exec_gread(oid, format, 0, in_file);
    free_odescr(specifier);
    fclose(in_file);
}
Beispiel #3
0
void exec_fwr(char* format){
    Odescr *specifier = pop_tstack();
    FILE *out = fopen(specifier->inst.sval, "w");
    if(out == NULL){
        machine_error("Could not open output file.");
    }
    exec_wr(format, 0, out);
    free_odescr(specifier);
    fclose(out);
}
Beispiel #4
0
void exec_cat(int num_fields, int size){
    int size_done = 0;
    int fields_done = 0;
    char *instance = newmem(size);
    while(fields_done < num_fields){
        Odescr *op = pop_tstack();
        int dest_start = size - size_done - op->size;
        // if there is an error reverse it, starting from 0 -- using size_done as index
        
        if(op->mode == EMB){
            switch(op->size){
                case sizeof(char): instance[dest_start] = op->inst.cval; break;
                case sizeof(int): *((int *)(instance+dest_start)) = op->inst.ival; break;
                case sizeof(char *):{
                    char *actual_address = instance+dest_start;
                    
                    char** act = (char **)actual_address;
                    act[0] = op->inst.sval;

                    //printf("%s %s\n",op->inst.sval, act[0]);
                    //printf("%p %s\n%p %s\n\n", act[0],act[0], op->inst.sval,op->inst.sval);
                    break;
                }
                default: machine_error("Unknown type for op->size"); break;
            }
        } else{
            memcpy(instance + dest_start, op->inst.sval, op->size);
        }
        size_done += op->size;
        fields_done++;
        free_odescr(op);
    }
    Odescr *op2 = push_tstack();
    op2->size = size;
    op2->mode = STA;
    op2->inst.sval = instance;
    // this allocates space on the instance stack and than copies byte by byte all the elements on the stack
    // taking them to the tstack (?)
    /*
        TSTACK:
        expr1_res
        expr2_res
        ...
    
        INSTANCE -> expr1_res, expr2_res, ...
    
        creates a single record on the tstack with SIZE, STA and with the pointer to the allocated instance
        
    */
}
Beispiel #5
0
  /* Implementation specific function */
  static inline database::create_node_fn
  get_creation_function(const scheduler_type sched_type)
  {

    switch(sched_type) {
    case SCHED_SERIAL:
      return database::create_node_fn(sched::serial_local::create_node);
    case SCHED_UNKNOWN:
      return NULL;
    default:
      return NULL;
    }

    throw machine_error("unknown scheduler type");

  }
Beispiel #6
0
void exec_ist(){
    Odescr *val = pop_tstack();
    Odescr *dest_addr = pop_tstack();
    Odescr *dest = dest_addr->original;
    
    if(dest->mode == EMB) {
        //printf("A\n");
        dest->inst = val->inst;
    } else{
        if(val->mode == EMB){
            //printf("B\n");
            char *instance = dest_addr->inst.sval;
            
            switch(val->size){
                case sizeof(int): { // works with float too
                    int *inst = (int *)instance;
                    inst[0] = val->inst.ival;
                    break;
                }
                case sizeof(char): {
                    char *inst = (char *)instance;
                    inst[0] = val->inst.cval;
                    break;
                }
                case sizeof(char *): {
                    char **inst = (char **)instance;
                    inst[0] = val->inst.sval;
                    break;
                }
                default: {
                    machine_error("Unrecognized size for IST.");
                    break;
                }
            }
        } else {
            //printf("C\n");
            memcpy(dest_addr->inst.sval, val->inst.sval, val->size);
        }
    }
    
    free_odescr(val);
    freemem((char *)dest_addr, sizeof(Odescr));
    // pop expression result
    // pop address
    // *adress = result
}
Beispiel #7
0
/**
 * @brief This functin opens the input file and do the initial memory allocation of data structures.
 * @param input the s_code filename.
 */
void start_machine(char * input) {
    str_const_table = (Str_c_node **)newmem(sizeof(Str_c_node*)*STR_CONST_DIM);
    FILE *input_file = fopen(input, "r");
    if (!input_file){
        machine_error("ERRORE nel caricamento del file");
    }
    load_scode(input_file);
    fclose (input_file);
    
    pc = ap = op = ip = 0;
    astack = (Adescr**)newmem(sizeof(Adescr*)*ASTACK_UNIT);
    asize = ASTACK_UNIT;
    ostack = (Odescr**)newmem(sizeof(Odescr*)*OSTACK_UNIT);
    osize = OSTACK_UNIT;
    istack = (char*)newmem(ISTACK_UNIT);
    isize = ISTACK_UNIT;
}
Beispiel #8
0
void exec_eil(int field_size){
    Odescr *address = pop_tstack();
    switch(field_size){
        case sizeof(int):{
            push_int(*((int *)address->inst.sval)); break;
        }
        case sizeof(char):{
            push_char(*((char *)address->inst.sval)); break;
        }
        case sizeof(char *):{
            char** act = (char **)address->inst.sval;
            push_string(act[0]); break;
        }
        default:{
            machine_error("EIL field_size error."); break;
        }
    }
    freemem((char*)address, sizeof(Odescr));
    // only dealloc the object and not the inst
}
Beispiel #9
0
int get_schema_size(Pschema schema){
    int size = 0;
    
    switch(schema->type){
        case TY_INT: size = sizeof(int); break;
        case TY_REAL: size = sizeof(float); break;
        case TY_CHAR: size = sizeof(char); break;
        case TY_BOOL: size = sizeof(char); break; // bool is '1' or '0'
        case TY_STRING: size = sizeof(char *); break;
        case TY_ARRAY: size = get_schema_size(schema->child)*schema->size; break;
        case TY_RECORD: {
            Pschema p = schema->child;
            while ( p != NULL ){
                size += get_schema_size( p->child ); // child of TY_ATTR
                p = p->brother;
            }
            break;
        }
        default: machine_error("Error in code generation: get_schema_size() default."); break;
    }
    
    return size;
}
Beispiel #10
0
void exec(Pystat stat){
    Arg arg0 = stat->args[0];
    Arg arg1 = stat->args[1];
    switch(stat->op){
        case Y_PUSH: {
            exec_push(arg0.ival, pc+1); // num_objects
            break;
        }
        case Y_GOTO: {
            exec_goto(arg0.ival); // absolute line
            break;
        }
        case Y_POP: {
            exec_pop();
            break;
        }
        case Y_NEW: {
            exec_new(arg0.ival); // obj size
            break;
        }
        case Y_NEWS: {
            exec_news(arg0.ival); // obj size
            break;
        }
        case Y_LDC: {
            exec_ldc(arg0.ival);
            break;
        }
        case Y_LDI: {
            exec_ldi(arg0.ival);
            break;
        }
        case Y_LDR: {
            exec_ldr(arg0.rval);
            break;
        }
        case Y_LDS: {
            exec_lds(arg0.sval);
            break;
        }
        case Y_LOD: {
            exec_lod(arg0.ival); // oid
            break;
        }
        case Y_GLOD: {
            exec_glod(arg0.ival); // oid
            break;
        }
        case Y_CAT: {
            exec_cat(arg0.ival, arg1.ival); // num fields, record/array size
            break;
        }
        case Y_LDA: {
            exec_lda(arg0.ival); // oid
            break;
        }
        case Y_GLDA: {
            exec_glda(arg0.ival); // oid
            break;
        }
        case Y_FDA: {
            exec_fda(arg0.ival); // field offset
            break;
        }
        case Y_EIL: {
            exec_eil(arg0.ival); // field size, embedded
            break;
        }
        case Y_SIL: {
            exec_sil(arg0.ival); // field size, on stack
            break;
        }
        case Y_IXA: {
            exec_ixa(arg0.ival); // elem size
            break;
        }
        case Y_STO: {
            exec_sto(arg0.ival); // oid
            break;
        }
        case Y_GSTO: {
            exec_gsto(arg0.ival); // oid
            break;
        }
        case Y_IST: {
            exec_ist(); // indirect store
            break;
        }
        case Y_JMF: {
            exec_jmf(arg0.ival); // offset
            break;
        }
        case Y_JMP: {
            exec_jmp(arg0.ival); // offset
            break;
        }
        case Y_EQU: {
            exec_equ(); // for all types of objects
            break;
        }
        case Y_NEQ: {
            exec_neq(); // for all types of objects
            break;
        }
        case Y_IGT: {
            exec_igt();
            break;
        }
        case Y_IGE: {
            exec_ige();
            break;
        }
        case Y_ILT: {
            exec_ilt();
            break;
        }
        case Y_ILE: {
            exec_ile();
            break;
        }
        case Y_RGT: {
            exec_rgt();
            break;
        }
        case Y_RGE: {
            exec_rge();
            break;
        }
        case Y_RLT: {
            exec_rlt();
            break;
        }
        case Y_RLE: {
            exec_rle();
            break;
        }
        case Y_SGT: {
            exec_sgt();
            break;
        }
        case Y_SGE: {
            exec_sge();
            break;
        }
        case Y_SLT: {
            exec_slt();
            break;
        }
        case Y_SLE: {
            exec_sle();
            break;
        }
        case Y_IPLUS: {
            exec_iplus();
            break;
        }
        case Y_IMINUS: {
            exec_iminus();
            break;
        }
        case Y_ITIMES: {
            exec_itimes();
            break;
        }
        case Y_IDIV: {
            exec_idiv();
            break;
        }
        case Y_RPLUS: {
            exec_rplus();
            break;
        }
        case Y_RMINUS: {
            exec_rminus();
            break;
        }
        case Y_RTIMES: {
            exec_rtimes();
            break;
        }
        case Y_RDIV: {
            exec_rdiv();
            break;
        }
        case Y_IUMI: {
            exec_iumi();
            break;
        }
        case Y_RUMI: {
            exec_rumi();
            break;
        }
        case Y_NEG: {
            exec_neg();
            break;
        }
        case Y_WR: {
            exec_wr(arg0.sval, 1, stdout); // schema
            break;
        }
        case Y_FWR: {
            exec_fwr(arg0.sval); // schema
            break;
        }
        case Y_RD: {
            exec_rd(arg0.sval, 1, stdin); // schema
            break;
        }
        case Y_FRD: {
            exec_frd(arg0.sval); // schema
            break;
        }
        case Y_TOINT: {
            exec_toint();
            break;
        }
        case Y_TOINTUP: {
            exec_tointup();
            break;
        }
        case Y_TOREAL: {
            exec_toreal();
            break;
        }
        case Y_READ: {
            exec_read(arg0.ival, arg1.sval, 1, stdin); // oid, schema
            break;
        }
        case Y_GREAD: {
            exec_gread(arg0.ival, arg1.sval, 1, stdin); // oid, schema
            break;
        }
        case Y_FREAD: {
            exec_fread(arg0.ival, arg1.sval); // oid, schema
            break;
        }
        case Y_GFREAD: {
            exec_gfread(arg0.ival, arg1.sval); // oid, schema
            break;
        }
        case Y_WRITE: {
            exec_write(arg0.sval); // schema
            break;
        }
        case Y_FWRITE: {
            exec_fwrite(arg0.sval); // schema
            break;
        }
        case Y_TDUP: {
            exec_tdup();
            break;
        }
        case Y_TPOP: {
            exec_tpop(arg0.ival); // num objects
            break;
        }
        case Y_MODULE: {
            // nothing to do here, the instruction is useless
            break;
        }
        case Y_RETURN: {
            exec_return();
            break;
        }
        default: {
            machine_error("Unknown instruction.");
            break;
        }
    }
}
Beispiel #11
0
void print_instance(char *instance, Pschema s, char *attr_name, int spaces, Mode mode, int pretty, FILE *out){
    if(attr_name!=NULL && pretty){
        print_spaces(spaces, out);
        fprintf(out, "WR for record attribute \"%s\"\n",attr_name);
    }
    if(pretty){
        print_spaces(spaces, out);
    }
    if(s->type == TY_RECORD || s->type == TY_ARRAY || s->type == TY_ATTR){
        switch(s->type){
            case TY_RECORD:{
                if(pretty){
                    fprintf(out, "WR for a record\n");
                }
                int printed_size = 0;
                Pschema temp = s->child;
                while(temp){
                    print_instance(instance + printed_size, temp->child, temp->id, spaces+1, mode, pretty, out);
                    printed_size += get_schema_size(temp->child);
                    temp = temp->brother;
                }
                break;
            }
            case TY_ARRAY:{
                int i;
                if(pretty){
                    fprintf(out, "WR for an array\n");
                }
                int field_size = get_schema_size(s->child);
                int nfields = s->size;
                for(i=0; i<nfields; i++){
                    print_instance(instance + field_size * i, s->child, NULL, spaces+1, mode, pretty, out);
                }
                break;
            }
            default: machine_error("TY_ATTR cannot be used in input_schema()."); break;
        }
    } else{
        if(mode == EMB){
            Arg inst;
            inst.sval = instance;
            if(pretty){
                fprintf(out, "WR ");
            }
            switch(s->type){
                case TY_INT: {
                    fprintf(out, "%d\n",inst.ival);
                    break;
                }
                case TY_CHAR: {
                    fprintf(out, "%c\n",inst.cval);
                    break;
                }
                case TY_REAL: {
                    fprintf(out, "%f\n",inst.rval);
                    break;
                }
                case TY_STRING: {
                    fprintf(out, "%s\n",inst.sval);
                    break;
                }
                case TY_BOOL: {
                    fprintf(out, "%s\n",inst.cval == '1' ? "true" : "false");
                    break;
                }
                default: {
                    break;
                }
            }
        } else{
            if(pretty){
                fprintf(out, "WR ");
            }
            switch(s->type){
                case TY_INT: {
                    int *inst = (int *)instance;
                    fprintf(out, "%d\n",inst[0]);
                    break;
                }
                case TY_CHAR: {
                    char *inst = (char *)instance;
                    fprintf(out, "%c\n",inst[0]);
                    break;
                }
                case TY_REAL: {
                    float *inst = (float *)instance;
                    fprintf(out, "%f\n",inst[0]);
                    break;
                }
                case TY_STRING: {
                    char **inst = (char **)instance;
                    fprintf(out, "%s\n",inst[0]);
                    break;
                }
                case TY_BOOL: {
                    char *inst = (char *)instance;
                    fprintf(out, "%s\n",inst[0] == '1' ? "true" : "false");
                    break;
                }
                default: {
                    break;
                }
            }
            
        }
    }
}
Beispiel #12
0
/**
 * return a pointer the top of the ostack.
 * @return The Odescr* on top of the astack.
 */
Odescr * top_ostack(){
    if (op==0) {
        machine_error("top_ostack");
    }
    return ostack[op-1];
}
Beispiel #13
0
/**
 * This function returns a pointer to the top of the astack.
 * @return The Adescr* on top of the astack.
 */
Adescr * top_astack(){
    if (ap==0) {
        machine_error("top_astack");
    }
    return astack[ap-1];
}
Beispiel #14
0
/**
 * @brief This function shift down the memory chunk express by to move of the quantity express by this much.
 * @param to_move how much bytes are to move.
 * @param this_much How much byte shift down the memory block
 */
void move_down_istack(int to_move, int this_much){
    if(ip - to_move - this_much < 0) machine_error("move_down_istack()");
    if (to_move<0 || this_much<0) machine_error("move_down_istack() parameters");
    memmove(&istack[ip-to_move-this_much], &istack[ip-to_move], to_move);
    ip -= this_much;
}
Beispiel #15
0
/**
 * @brief Decrement the istack with the size and return the new top.
 *
 * @param size how much increment the istack.
 */
void pop_istack(int size) {
    if(ip < size) machine_error("pop_istack()");
    ip = ip-size;
}
Beispiel #16
0
/**
 * @brief Free the odescr on the top of the ostack.
 */
void pop_ostack() {
    if(op == 0) machine_error("pop_odescr()");
    freemem((char*)ostack[--op], sizeof(Odescr));
}
Beispiel #17
0
/**
 * return a pointer the element below the element on top of the ostack.
 * @return The Odescr* to the Odescr below the Odescr on top of the astack.
 */
Odescr * under_top_ostack(){
    if (op<=1) {
        machine_error("under_top_ostack");
    }
    return ostack[op-2];
}
Beispiel #18
0
void input_schema(Pschema s, char *attr_name, int spaces, int pretty, FILE *in_file){ // reads a schema and puts it on the top op tstack
    if(attr_name!=NULL && pretty){
        print_spaces(spaces, stdout);
        fprintf(stdout, "Input record attribute \"%s\"\n",attr_name);
    }
    if(pretty){
        print_spaces(spaces, stdout);
    }
    if(s->type == TY_RECORD || s->type == TY_ARRAY || s->type == TY_ATTR){
        int size = get_schema_size(s);
        int nfields = 0;
        switch(s->type){
            case TY_RECORD:{
                if(pretty){
                    fprintf(stdout,"Input for a record\n");
                }
                Pschema temp = s->child;
                while(temp){
                    input_schema(temp->child, temp->id, spaces+1, pretty, in_file);
                    nfields++;
                    temp = temp->brother;
                }
                break;
            }
            case TY_ARRAY:{
                int i;
                if(pretty){
                    fprintf(stdout, "Input for an array\n");
                }
                nfields = s->size;
                for(i=0; i<nfields; i++){
                    input_schema(s->child, NULL, spaces+1, pretty, in_file);
                }
                break;
            }
            default: print_schema(s,0); machine_error("TY_ATTR cannot be used in input_schema()."); break;
        }
        exec_cat(nfields,size);
    } else{
        switch(s->type){
            case TY_INT: {
                int in = read_int(stdout, in_file, "Insert an integer: ", pretty);
                push_int(in);
                break;
            }
            case TY_CHAR: {
                char in = read_char(stdout, in_file, "Insert a char: ", pretty);
                push_char(in);
                break;
            }
            case TY_REAL: {
                float in = read_real(stdout, in_file, "Insert a number of type real: ", pretty);
                push_real(in);
                break;
            }
            case TY_STRING: {
                char *in = read_string(stdout, in_file, "Insert a string: ", pretty);
                char *strig_to_store = stringtable_store(in, stringtable);
                freemem(in, strlen(in) + 1);
                push_string(strig_to_store);
                break;
            }
            case TY_BOOL: {
                char in = read_char(stdout, in_file, "Insert a boolean (0 or 1): ", pretty);
                push_bool(in == '1');
                break;
            }
            default: {machine_error("Unknown type of schema in input_schema()."); break;}
        }
    }
}
Beispiel #19
0
/**
 * @brief Free the adescr on the top of the astack.
 */
void pop_astack() {
    if(ap == 0) machine_error("pop_adescr()");
    freemem((char*)astack[--ap], sizeof(Adescr));
}