<commit_before>/*
 *  caosVM.cpp
 *  openc2e
 *
 *  Created by <NAME> on Tue May 25 2004.
 *  Copyright (c) 2004 <NAME>. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "caosVM.h"
#include "openc2e.h"
#include "World.h"
#include "bytecode.h"
#include <iostream>

using std::cout;
using std::cerr;
using std::endl;

class caosAbort : public caosOp {
	public:
		void execute(caosVM *vm) {
			cerr << "Bad! Some opcode forgot to set its successor" << endl;
			caos_assert(false);
		}
} abortop;

caosVM::caosVM(const AgentRef &o)
	: vm(this)
{
	owner = o;
	currentscript.reset();
	cip = nip = 0;
	blocking = NULL;
	inputstream = 0; outputstream = 0;
	resetCore();
	trace = false;
}

bool caosVM::isBlocking() {
	if (!blocking) return false;
	bool bl = (*blocking)();
	if (!bl) {
		delete blocking;
		blocking = NULL;
	}
	return bl;
}

void caosVM::startBlocking(blockCond *whileWhat) {
	if (!owner)
		// TODO: should this just fail to block?
		throw creaturesException("trying to block in a non-blockable script");
	inst = false;
	if (blocking)
		throw creaturesException("trying to block with a block condition in-place");
	blocking = whileWhat;
}

inline void caosVM::runOp() {
	cip = nip;
	nip++;
	shared_ptr<script> scr = currentscript;
	caosOp *op = currentscript->getOp(cip);
	if (!op) {
		stop();
		return;
	}
	result.reset(); // xxx this belongs in opcode maybe
	try {
		if (trace) {
			fprintf(stderr, "Trace: %08d ", cip);
			std::cerr << op->dump() << std::endl;
		}
		op->execute(this);
	} catch (creaturesException &e) {
		//std::cerr << "script stopped due to exception " << e.what() << endl;
		stop();
		throw;
	} catch (caosException &e) {
		e.trace(scr->filename.c_str(), op->getlineno(), scr, op);
		//std::cerr << "script stopped due to exception " << e.what() << endl;
		stop();
		throw;
	}
	if (!result.isNull())
		valueStack.push_back(result);
}

void caosVM::stop() {
	cip = nip = 0;
	lock = false;
	currentscript.reset();
}

void caosVM::runEntirely(shared_ptr<script> s) {
	currentscript = s;
	cip = nip = 0;
	while (true) {
		runOp();
		if (!currentscript) break;
		if (blocking) {
			delete blocking;
			blocking = NULL;
			throw creaturesException("blocking in an installation script");
		}
	}
	stop(); // probably redundant, but eh
}

bool caosVM::fireScript(shared_ptr<script> s, bool nointerrupt, Agent *frm) {
	assert(owner);
	assert(s);
	if (lock) return false; // can't interrupt scripts which called LOCK
	if (currentscript && nointerrupt) return false; // don't interrupt scripts with a timer script

	resetScriptState();
	currentscript = s;
	cip = nip = 0;
	targ = owner;
	from.set(frm);
	timeslice = 1;
	return true;
}

void caosVM::resetScriptState() {
	stop();
	resetCore();
}

void caosVM::resetCore() {
	if (blocking)
		delete blocking;
	blocking = NULL;
	
	valueStack.clear();
	callStack.clear();

	inst = lock = 0;
	timeslice = 0;

	c_FILE_ICLO(); // make sure input stream is freed
	inputstream = 0; // .. possibly not strictly necessary, when all is bugfree
	c_FILE_OCLO(); // make sure output stream is freed
	outputstream = &cout;

	_it_ = NULL;
	from = NULL;
	setTarg(owner);
	part = 0;

	_p_[0].reset(); _p_[0].setInt(0); _p_[1].reset(); _p_[1].setInt(0);
	for (unsigned int i = 0; i < 100; i++) { var[i].reset(); var[i].setInt(0); }

	camera.reset();
}

void caosVM::tick() {
	stop_loop = false;
	while (currentscript && !stop_loop && (timeslice > 0 || inst)) {
		if (isBlocking()) return;
		runOp();
	}
}

/* vim: set noet: */<commit_msg>Some trace formatting tweaks; also reset tracing flag when the VM is reset<commit_after>/*
 *  caosVM.cpp
 *  openc2e
 *
 *  Created by <NAME> on Tue May 25 2004.
 *  Copyright (c) 2004 <NAME>. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "caosVM.h"
#include "openc2e.h"
#include "World.h"
#include "bytecode.h"
#include <iostream>

using std::cout;
using std::cerr;
using std::endl;

class caosAbort : public caosOp {
	public:
		void execute(caosVM *vm) {
			cerr << "Bad! Some opcode forgot to set its successor" << endl;
			caos_assert(false);
		}
} abortop;

caosVM::caosVM(const AgentRef &o)
	: vm(this)
{
	owner = o;
	currentscript.reset();
	cip = nip = 0;
	blocking = NULL;
	inputstream = 0; outputstream = 0;
	resetCore();
	trace = false;
}

bool caosVM::isBlocking() {
	if (!blocking) return false;
	bool bl = (*blocking)();
	if (!bl) {
		delete blocking;
		blocking = NULL;
	}
	return bl;
}

void caosVM::startBlocking(blockCond *whileWhat) {
	if (!owner)
		// TODO: should this just fail to block?
		throw creaturesException("trying to block in a non-blockable script");
	inst = false;
	if (blocking)
		throw creaturesException("trying to block with a block condition in-place");
	blocking = whileWhat;
}

inline void caosVM::runOp() {
	cip = nip;
	nip++;
	shared_ptr<script> scr = currentscript;
	caosOp *op = currentscript->getOp(cip);
	if (!op) {
		stop();
		return;
	}
	result.reset(); // xxx this belongs in opcode maybe
	try {
		if (trace) {
			std::cerr
				<< boost::str(boost::format("optrace: %p @%08d ") % (void *)this % cip)
				<< op->dump() << std::endl;
		}
		op->execute(this);
	} catch (creaturesException &e) {
		//std::cerr << "script stopped due to exception " << e.what() << endl;
		stop();
		throw;
	} catch (caosException &e) {
		e.trace(scr->filename.c_str(), op->getlineno(), scr, op);
		//std::cerr << "script stopped due to exception " << e.what() << endl;
		stop();
		throw;
	}
	if (!result.isNull())
		valueStack.push_back(result);
}

void caosVM::stop() {
	cip = nip = 0;
	lock = false;
	currentscript.reset();
}

void caosVM::runEntirely(shared_ptr<script> s) {
	currentscript = s;
	cip = nip = 0;
	while (true) {
		runOp();
		if (!currentscript) break;
		if (blocking) {
			delete blocking;
			blocking = NULL;
			throw creaturesException("blocking in an installation script");
		}
	}
	stop(); // probably redundant, but eh
}

bool caosVM::fireScript(shared_ptr<script> s, bool nointerrupt, Agent *frm) {
	assert(owner);
	assert(s);
	if (lock) return false; // can't interrupt scripts which called LOCK
	if (currentscript && nointerrupt) return false; // don't interrupt scripts with a timer script

	resetScriptState();
	currentscript = s;
	cip = nip = 0;
	targ = owner;
	from.set(frm);
	timeslice = 1;
	return true;
}

void caosVM::resetScriptState() {
	stop();
	resetCore();
}

void caosVM::resetCore() {
	if (blocking)
		delete blocking;
	blocking = NULL;
	
	valueStack.clear();
	callStack.clear();

	inst = lock = 0;
	timeslice = 0;

	c_FILE_ICLO(); // make sure input stream is freed
	inputstream = 0; // .. possibly not strictly necessary, when all is bugfree
	c_FILE_OCLO(); // make sure output stream is freed
	outputstream = &cout;

	_it_ = NULL;
	from = NULL;
	setTarg(owner);
	part = 0;

	_p_[0].reset(); _p_[0].setInt(0); _p_[1].reset(); _p_[1].setInt(0);
	for (unsigned int i = 0; i < 100; i++) { var[i].reset(); var[i].setInt(0); }

	camera.reset();

	trace = false;
}

void caosVM::tick() {
	stop_loop = false;
	while (currentscript && !stop_loop && (timeslice > 0 || inst)) {
		if (isBlocking()) return;
		runOp();
	}
}

/* vim: set noet: */
{'fraction_non_alphanumeric': 0.1453896343715376, 'fraction_numerical': 0.00935614920595839, 'mean_word_length': 3.8071005917159764, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3036948', 'n_tokens_mistral': 3045, 'n_tokens_neox': 2853, 'n_words': 896}