Beispiel #1
0
static int backup_dir(FILE* fh, const char* srcPath)
{
    DIR *dir;
    struct dirent *de;
    char* fullPath = NULL;
    int srcLen = strlen(srcPath);
    int result = 1;
    int i;
    
    dir = opendir(srcPath);

    if (dir == NULL) {
        fprintf (stderr, "error opendir'ing '%s': %s\n",
                    srcPath, strerror(errno));
        return 0;
    }
    
    for (;;) {
        de = readdir(dir);

        if (de == NULL) {
            break;
        }

        if (0 == strcmp(de->d_name, ".")
                || 0 == strcmp(de->d_name, "..")
                || 0 == strcmp(de->d_name, "lost+found")
        ) {
            continue;
        }

        if (fullPath == NULL) {
            free(fullPath);
        }
        fullPath = (char*)malloc(srcLen + strlen(de->d_name) + 2);
        strcpy(fullPath, srcPath);
        fullPath[srcLen] = '/';
        strcpy(fullPath+srcLen+1, de->d_name);

        /* See if this is a path we should skip. */
        if (!opt_backupAll) {
            for (i = 0; SKIP_PATHS[i].path; i++) {
                if (strcmp(SKIP_PATHS[i].path, fullPath) == 0) {
                    break;
                }
            }
            if (SKIP_PATHS[i].path != NULL) {
                continue;
            }
        }

        int ret = lstat(fullPath, &statBuffer);

        if (ret != 0) {
            fprintf(stderr, "stat() error on '%s': %s\n", 
                    fullPath, strerror(errno));
            result = 0;
            goto done;
        }

        if(S_ISDIR(statBuffer.st_mode)) {
            printf("Saving dir %s...\n", fullPath);
            
            if (write_header(fh, TYPE_DIR, fullPath, &statBuffer) == 0) {
                result = 0;
                goto done;
            }
            if (backup_dir(fh, fullPath) == 0) {
                result = 0;
                goto done;
            }
        } else if (S_ISREG(statBuffer.st_mode)) {
            printf("Saving file %s...\n", fullPath);
            
            if (write_header(fh, TYPE_FILE, fullPath, &statBuffer) == 0) {
                result = 0;
                goto done;
            }
            
            off_t size = statBuffer.st_size;
            if (!write_int64(fh, size)) {
                result = 0;
                goto done;
            }
            
            FILE* src = fopen(fullPath, "r");
            if (src == NULL) {
                fprintf(stderr, "unable to open source file '%s': %s\n",
                    fullPath, strerror(errno));
                result = 0;
                goto done;
            }
            
            int copyres = copy_file(fh, src, size, NULL, fullPath);
            fclose(src);
            if (!copyres) {
                result = 0;
                goto done;
            }
        }
    }

done:
    if (fullPath != NULL) {
        free(fullPath);
    }
    
    closedir(dir);
    
    return result;
}
Beispiel #2
0
/* Writes instructions within a basic block boundary. */
static void write_instructions(MVMThreadContext *tc, MVMSpeshGraph *g, SpeshWriterState *ws, MVMSpeshBB *bb) {
    MVMSpeshIns *ins = bb->first_ins;
    while (ins) {
        MVMint32 i;

        /* Process any annotations. */
        MVMSpeshAnn *ann              = ins->annotations;
        MVMSpeshAnn *deopt_one_ann    = NULL;
        MVMSpeshAnn *deopt_all_ann    = NULL;
        MVMSpeshAnn *deopt_inline_ann = NULL;
        while (ann) {
            switch (ann->type) {
            case MVM_SPESH_ANN_FH_START:
                ws->handlers[ann->data.frame_handler_index].start_offset =
                    ws->bytecode_pos;
                break;
            case MVM_SPESH_ANN_FH_END:
                ws->handlers[ann->data.frame_handler_index].end_offset =
                    ws->bytecode_pos;
                break;
            case MVM_SPESH_ANN_FH_GOTO:
                ws->handlers[ann->data.frame_handler_index].goto_offset =
                    ws->bytecode_pos;
                break;
            case MVM_SPESH_ANN_DEOPT_ONE_INS:
                deopt_one_ann = ann;
                break;
            case MVM_SPESH_ANN_DEOPT_ALL_INS:
                deopt_all_ann = ann;
                break;
            case MVM_SPESH_ANN_INLINE_START:
                g->inlines[ann->data.inline_idx].start = ws->bytecode_pos;
                break;
            case MVM_SPESH_ANN_INLINE_END:
                g->inlines[ann->data.inline_idx].end = ws->bytecode_pos;
                break;
            case MVM_SPESH_ANN_DEOPT_INLINE:
                deopt_inline_ann = ann;
                break;
            case MVM_SPESH_ANN_DEOPT_OSR:
                g->deopt_addrs[2 * ann->data.deopt_idx + 1] = ws->bytecode_pos;
                break;
            }
            ann = ann->next;
        }

        if (ins->info->opcode != MVM_SSA_PHI) {
            /* Real instruction, not a phi. Emit opcode. */
            if (ins->info->opcode == (MVMuint16)-1) {
                /* Ext op; resolve. */
                MVMExtOpRecord *extops     = g->sf->body.cu->body.extops;
                MVMuint16       num_extops = g->sf->body.cu->body.num_extops;
                MVMint32        found      = 0;
                for (i = 0; i < num_extops; i++) {
                    if (extops[i].info == ins->info) {
                        write_int16(ws, MVM_OP_EXT_BASE + i);
                        found = 1;
                        break;
                    }
                }
                if (!found)
                    MVM_oops(tc, "Spesh: failed to resolve extop in code-gen");
            }
            else {
                /* Core op. */
                write_int16(ws, ins->info->opcode);
            }

            /* Write out operands. */
            for (i = 0; i < ins->info->num_operands; i++) {
                MVMuint8 flags = ins->info->operands[i];
                MVMuint8 rw    = flags & MVM_operand_rw_mask;
                switch (rw) {
                case MVM_operand_read_reg:
                case MVM_operand_write_reg:
                    write_int16(ws, ins->operands[i].reg.orig);
                    break;
                case MVM_operand_read_lex:
                case MVM_operand_write_lex:
                    write_int16(ws, ins->operands[i].lex.idx);
                    write_int16(ws, ins->operands[i].lex.outers);
                    break;
                case MVM_operand_literal: {
                    MVMuint8 type = flags & MVM_operand_type_mask;
                    switch (type) {
                    case MVM_operand_int8:
                        write_int8(ws, ins->operands[i].lit_i8);
                        break;
                    case MVM_operand_int16:
                        write_int16(ws, ins->operands[i].lit_i16);
                        break;
                    case MVM_operand_int32:
                        write_int32(ws, ins->operands[i].lit_i32);
                        break;
                    case MVM_operand_int64:
                        write_int64(ws, ins->operands[i].lit_i64);
                        break;
                    case MVM_operand_num32:
                        write_num32(ws, ins->operands[i].lit_n32);
                        break;
                    case MVM_operand_num64:
                        write_num64(ws, ins->operands[i].lit_n64);
                        break;
                    case MVM_operand_callsite:
                        write_int16(ws, ins->operands[i].callsite_idx);
                        break;
                    case MVM_operand_coderef:
                        write_int16(ws, ins->operands[i].coderef_idx);
                        break;
                    case MVM_operand_str:
                        write_int32(ws, ins->operands[i].lit_str_idx);
                        break;
                    case MVM_operand_ins: {
                        MVMint32 offset = ws->bb_offsets[ins->operands[i].ins_bb->idx];
                        if (offset >= 0) {
                            /* Already know where it is, so just write it. */
                            write_int32(ws, offset);
                        }
                        else {
                            /* Need to fix it up. */
                            if (ws->num_fixups == ws->alloc_fixups) {
                                ws->alloc_fixups *= 2;
                                ws->fixup_locations = MVM_realloc(ws->fixup_locations,
                                    ws->alloc_fixups * sizeof(MVMint32));
                                ws->fixup_bbs = MVM_realloc(ws->fixup_bbs,
                                    ws->alloc_fixups * sizeof(MVMSpeshBB *));
                            }
                            ws->fixup_locations[ws->num_fixups] = ws->bytecode_pos;
                            ws->fixup_bbs[ws->num_fixups]       = ins->operands[i].ins_bb;
                            write_int32(ws, 0);
                            ws->num_fixups++;
                        }
                        break;
                    }
                    case MVM_operand_spesh_slot:
                        write_int16(ws, ins->operands[i].lit_i16);
                        break;
                    default:
                        MVM_oops(tc,
                            "Spesh: unknown operand type %d in codegen (op %s)",
                            (int)type, ins->info->name);
                    }
                    }
                    break;
                default:
                    MVM_oops(tc, "Spesh: unknown operand type in codegen");
                }
            }
        }

        /* If there was a deopt point annotation, update table. */
        if (deopt_one_ann)
            g->deopt_addrs[2 * deopt_one_ann->data.deopt_idx + 1] = ws->bytecode_pos;
        if (deopt_all_ann)
            g->deopt_addrs[2 * deopt_all_ann->data.deopt_idx + 1] = ws->bytecode_pos;
        if (deopt_inline_ann)
            g->deopt_addrs[2 * deopt_inline_ann->data.deopt_idx + 1] = ws->bytecode_pos;

        ins = ins->next;
    }
}