Пример #1
0
//! Lecture  (à travers le cache).
Cache_Error Cache_Read(struct Cache *pcache, int irfile, void *precord)
{
	if(CheckSync(pcache))
		Cache_Sync(pcache);

	int ibfile = (int)(irfile/pcache->nrecords);
	struct Cache_Block_Header *cbh = NULL;
	
	for(struct Cache_Block_Header *h = pcache->headers; h < (pcache->headers + pcache->nblocks); h++)
	{
		if(h->ibfile == ibfile && (h->flags & VALID))
		{
			cbh = h;
			pcache->instrument.n_hits++;
			break;
		}
	}
	
	if(!cbh)
	{				
		cbh = Strategy_Replace_Block(pcache);
		if(!cbh)
			cbh = pcache->headers;

		
		if(cbh->flags&MODIF)
		{
			fseek(pcache->fp, DADDR(pcache, cbh->ibfile), SEEK_SET);
			fwrite(cbh->data, pcache->blocksz, 1, pcache->fp);
		}
		
		cbh->ibfile = ibfile;
		cbh->flags = VALID;
		fseek(pcache->fp, DADDR(pcache, ibfile), SEEK_SET);
		fread(cbh->data, pcache->blocksz, 1, pcache->fp);
	}

	memcpy(precord, ADDR(pcache, irfile, cbh), pcache->recordsz); 
	
	pcache->instrument.n_reads++;

	Strategy_Read(pcache, cbh);
	
	return CACHE_OK;
}
Пример #2
0
/*! \brief Écriture physique d'un bloc dans le fichier.
 * 
 *  \ingroup cache_internal
 *
 * On écrit le bloc puis on efface le flag de modification.
 * 
 * \param pcache un pointeur sur le cache
 * \param un pointeur sur le bloc du cache à écrire
 * \return un code d'erreur
 */
static Cache_Error Write_Block(struct Cache *pcache, struct Cache_Block_Header *pbh)
{
    /* On positionne le pointeur d'E/S à l'adresse du bloc dans le fichier */
    fseek(pcache->fp, DADDR(pcache, pbh->ibfile), SEEK_SET);

    /* On écrit les données du bloc */
    if (fwrite(pbh->data, 1, pcache->blocksz, pcache->fp) != pcache->blocksz)
	return CACHE_KO;

    /* On efface la marque de modification */  
    pbh->flags &= ~MODIF;

    return CACHE_OK;
}
Пример #3
0
//! Synchronisation du cache.
Cache_Error Cache_Sync(struct Cache *pcache)
{	
	for(struct Cache_Block_Header *h = pcache->headers; h < (pcache->headers + pcache->nblocks); h++)
	{
		if(h->flags & MODIF)
		{
			h->flags &= ~MODIF;
			fseek(pcache->fp, DADDR(pcache, h->ibfile), SEEK_SET);
			fwrite(h->data, pcache->blocksz, 1, pcache->fp);
		}
	}
	pcache->instrument.n_syncs++;
	
	return CACHE_OK;
}
Пример #4
0
/*! \brief Lecture physique d'un bloc depuis le fichier.
 *
 *  \ingroup cache_internal
 *
 * Si le bloc correspond à des enregistrements existants actuellement sur le
 * fichier, on écrase juste les données du fichier par celles du bloc. S'il
 * est dela de la fin de fichier, on cree un bloc de zéros. Dans tous les cas
 * on valide le bloc.
 * 
 * \param pcache un pointeur sur le cache
 * \param un pointeur sur le bloc du cache à écrire
 * \return un code d'erreur
 */
static Cache_Error Read_Block(struct Cache *pcache, struct Cache_Block_Header *pbh)
{
    long loff, leof;

    /* On cherche la longueur courante du fichier */
    if (fseek(pcache->fp, 0, SEEK_END) < 0) return CACHE_KO;
    leof = ftell(pcache->fp);

    /* Si l'on est au dela de la fin de fichier, on cree un bloc de zeros.
       Sinon, on lit le bloc depuis le fichier */

    loff = DADDR(pcache, pbh->ibfile); /* Adresse en octets du bloc dans le fichier */

    if (loff >= leof)
    {
        /* Le bloc cherché est au dela de la fin de fichier. */

        /* On n'effectue aucune entrée-sortie, se contentant de mettre le bloc à 0. */
        memset(pbh->data, '\0', pcache->blocksz); 
    }
    else 
    { 
        /* Le bloc existe dans le fichier */

        /* On y va ! */
	if (fseek(pcache->fp, loff, SEEK_SET) != 0) return CACHE_KO; 

        /* Et on le lit */
	if (fread(pbh->data, 1, pcache->blocksz, pcache->fp) != pcache->blocksz)
	    return CACHE_KO; 
    } 

    /* Le bloc est maintenant valide */
    pbh->flags |= VALID;

    return CACHE_OK;
}
Пример #5
0
static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String> &p_code) {

	const Map<StringName, GDScriptFunction *> &mf = p_class->debug_get_member_functions();

	for (const Map<StringName, GDScriptFunction *>::Element *E = mf.front(); E; E = E->next()) {

		const GDScriptFunction &func = *E->get();
		const int *code = func.get_code();
		int codelen = func.get_code_size();
		String defargs;
		if (func.get_default_argument_count()) {
			defargs = "defarg at: ";
			for (int i = 0; i < func.get_default_argument_count(); i++) {

				if (i > 0)
					defargs += ",";
				defargs += itos(func.get_default_argument_addr(i));
			}
			defargs += " ";
		}
		print_line("== function " + String(func.get_name()) + "() :: stack size: " + itos(func.get_max_stack_size()) + " " + defargs + "==");

#define DADDR(m_ip) (_disassemble_addr(p_class, func, code[ip + m_ip]))

		for (int ip = 0; ip < codelen;) {

			int incr = 0;
			String txt = itos(ip) + " ";

			switch (code[ip]) {

				case GDScriptFunction::OPCODE_OPERATOR: {

					int op = code[ip + 1];
					txt += "op ";

					String opname = Variant::get_operator_name(Variant::Operator(op));

					txt += DADDR(4);
					txt += " = ";
					txt += DADDR(2);
					txt += " " + opname + " ";
					txt += DADDR(3);
					incr += 5;

				} break;
				case GDScriptFunction::OPCODE_SET: {

					txt += "set ";
					txt += DADDR(1);
					txt += "[";
					txt += DADDR(2);
					txt += "]=";
					txt += DADDR(3);
					incr += 4;

				} break;
				case GDScriptFunction::OPCODE_GET: {

					txt += " get ";
					txt += DADDR(3);
					txt += "=";
					txt += DADDR(1);
					txt += "[";
					txt += DADDR(2);
					txt += "]";
					incr += 4;

				} break;
				case GDScriptFunction::OPCODE_SET_NAMED: {

					txt += " set_named ";
					txt += DADDR(1);
					txt += "[\"";
					txt += func.get_global_name(code[ip + 2]);
					txt += "\"]=";
					txt += DADDR(3);
					incr += 4;

				} break;
				case GDScriptFunction::OPCODE_GET_NAMED: {

					txt += " get_named ";
					txt += DADDR(3);
					txt += "=";
					txt += DADDR(1);
					txt += "[\"";
					txt += func.get_global_name(code[ip + 2]);
					txt += "\"]";
					incr += 4;

				} break;
				case GDScriptFunction::OPCODE_SET_MEMBER: {

					txt += " set_member ";
					txt += "[\"";
					txt += func.get_global_name(code[ip + 1]);
					txt += "\"]=";
					txt += DADDR(2);
					incr += 3;

				} break;
				case GDScriptFunction::OPCODE_GET_MEMBER: {

					txt += " get_member ";
					txt += DADDR(2);
					txt += "=";
					txt += "[\"";
					txt += func.get_global_name(code[ip + 1]);
					txt += "\"]";
					incr += 3;

				} break;
				case GDScriptFunction::OPCODE_ASSIGN: {

					txt += " assign ";
					txt += DADDR(1);
					txt += "=";
					txt += DADDR(2);
					incr += 3;

				} break;
				case GDScriptFunction::OPCODE_ASSIGN_TRUE: {

					txt += " assign ";
					txt += DADDR(1);
					txt += "= true";
					incr += 2;

				} break;
				case GDScriptFunction::OPCODE_ASSIGN_FALSE: {

					txt += " assign ";
					txt += DADDR(1);
					txt += "= false";
					incr += 2;

				} break;
				case GDScriptFunction::OPCODE_CONSTRUCT: {

					Variant::Type t = Variant::Type(code[ip + 1]);
					int argc = code[ip + 2];

					txt += " construct ";
					txt += DADDR(3 + argc);
					txt += " = ";

					txt += Variant::get_type_name(t) + "(";
					for (int i = 0; i < argc; i++) {

						if (i > 0)
							txt += ", ";
						txt += DADDR(i + 3);
					}
					txt += ")";

					incr = 4 + argc;

				} break;
				case GDScriptFunction::OPCODE_CONSTRUCT_ARRAY: {

					int argc = code[ip + 1];
					txt += " make_array ";
					txt += DADDR(2 + argc);
					txt += " = [ ";

					for (int i = 0; i < argc; i++) {
						if (i > 0)
							txt += ", ";
						txt += DADDR(2 + i);
					}

					txt += "]";

					incr += 3 + argc;

				} break;
				case GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY: {

					int argc = code[ip + 1];
					txt += " make_dict ";
					txt += DADDR(2 + argc * 2);
					txt += " = { ";

					for (int i = 0; i < argc; i++) {
						if (i > 0)
							txt += ", ";
						txt += DADDR(2 + i * 2 + 0);
						txt += ":";
						txt += DADDR(2 + i * 2 + 1);
					}

					txt += "}";

					incr += 3 + argc * 2;

				} break;

				case GDScriptFunction::OPCODE_CALL:
				case GDScriptFunction::OPCODE_CALL_RETURN: {

					bool ret = code[ip] == GDScriptFunction::OPCODE_CALL_RETURN;

					if (ret)
						txt += " call-ret ";
					else
						txt += " call ";

					int argc = code[ip + 1];
					if (ret) {
						txt += DADDR(4 + argc) + "=";
					}

					txt += DADDR(2) + ".";
					txt += String(func.get_global_name(code[ip + 3]));
					txt += "(";

					for (int i = 0; i < argc; i++) {
						if (i > 0)
							txt += ", ";
						txt += DADDR(4 + i);
					}
					txt += ")";

					incr = 5 + argc;

				} break;
				case GDScriptFunction::OPCODE_CALL_BUILT_IN: {

					txt += " call-built-in ";

					int argc = code[ip + 2];
					txt += DADDR(3 + argc) + "=";

					txt += GDScriptFunctions::get_func_name(GDScriptFunctions::Function(code[ip + 1]));
					txt += "(";

					for (int i = 0; i < argc; i++) {
						if (i > 0)
							txt += ", ";
						txt += DADDR(3 + i);
					}
					txt += ")";

					incr = 4 + argc;

				} break;
				case GDScriptFunction::OPCODE_CALL_SELF_BASE: {

					txt += " call-self-base ";

					int argc = code[ip + 2];
					txt += DADDR(3 + argc) + "=";

					txt += func.get_global_name(code[ip + 1]);
					txt += "(";

					for (int i = 0; i < argc; i++) {
						if (i > 0)
							txt += ", ";
						txt += DADDR(3 + i);
					}
					txt += ")";

					incr = 4 + argc;

				} break;
				case GDScriptFunction::OPCODE_YIELD: {

					txt += " yield ";
					incr = 1;

				} break;
				case GDScriptFunction::OPCODE_YIELD_SIGNAL: {

					txt += " yield_signal ";
					txt += DADDR(1);
					txt += ",";
					txt += DADDR(2);
					incr = 3;
				} break;
				case GDScriptFunction::OPCODE_YIELD_RESUME: {

					txt += " yield resume: ";
					txt += DADDR(1);
					incr = 2;
				} break;
				case GDScriptFunction::OPCODE_JUMP: {

					txt += " jump ";
					txt += itos(code[ip + 1]);

					incr = 2;

				} break;
				case GDScriptFunction::OPCODE_JUMP_IF: {

					txt += " jump-if ";
					txt += DADDR(1);
					txt += " to ";
					txt += itos(code[ip + 2]);

					incr = 3;
				} break;
				case GDScriptFunction::OPCODE_JUMP_IF_NOT: {

					txt += " jump-if-not ";
					txt += DADDR(1);
					txt += " to ";
					txt += itos(code[ip + 2]);

					incr = 3;
				} break;
				case GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT: {

					txt += " jump-to-default-argument ";
					incr = 1;
				} break;
				case GDScriptFunction::OPCODE_RETURN: {

					txt += " return ";
					txt += DADDR(1);

					incr = 2;

				} break;
				case GDScriptFunction::OPCODE_ITERATE_BEGIN: {

					txt += " for-init " + DADDR(4) + " in " + DADDR(2) + " counter " + DADDR(1) + " end " + itos(code[ip + 3]);
					incr += 5;

				} break;
				case GDScriptFunction::OPCODE_ITERATE: {

					txt += " for-loop " + DADDR(4) + " in " + DADDR(2) + " counter " + DADDR(1) + " end " + itos(code[ip + 3]);
					incr += 5;

				} break;
				case GDScriptFunction::OPCODE_LINE: {

					int line = code[ip + 1] - 1;
					if (line >= 0 && line < p_code.size())
						txt = "\n" + itos(line + 1) + ": " + p_code[line] + "\n";
					else
						txt = "";
					incr += 2;
				} break;
				case GDScriptFunction::OPCODE_END: {

					txt += " end";
					incr += 1;
				} break;
				case GDScriptFunction::OPCODE_ASSERT: {

					txt += " assert ";
					txt += DADDR(1);
					incr += 2;

				} break;
			}

			if (incr == 0) {

				ERR_EXPLAIN("unhandled opcode: " + itos(code[ip]));
				ERR_BREAK(incr == 0);
			}

			ip += incr;
			if (txt != "")
				print_line(txt);
		}
	}
}