CScript 割り込み実装 default tip
authorissei@issei.org
Sun Jul 01 20:15:56 2007 +0900 (18 months ago)
changeset 495baf193f57c64
parent 494b3c8c862cece
CScript 割り込み実装
SCBファイルに割り込みセクションを用意し、SCBファイル読み込み時に自動設定
tool/src/cscript/code/cast_def.h
tool/src/cscript/code/comp.cc
tool/src/cscript/code/comp.h
tool/src/cscript/code/cscds_main.cc
tool/src/cscript/code/cscvm_main.cc
tool/src/cscript/code/dump.cc
tool/src/cscript/code/dump.h
tool/src/cscript/code/file.h
tool/src/cscript/code/lex.l
tool/src/cscript/code/parser.y
tool/src/cscript/code/vm.cc
tool/src/cscript/code/vm.h
tool/src/cscript/code/vm_cast.h
tool/src/cscript/code/vm_loader.cc
tool/src/cscript/code/vm_loader.h
tool/src/cscript/cscript/cscript.sch
tool/src/cscript/cscript/system.sch
tool/src/cscript/m4/keyword.m4
tool/src/cscript/mk/cscript.mak
tool/src/cscript/sample/intr.sch
tool/src/cscript/sample/intr.scs
--- a/tool/src/cscript/code/cast_def.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/cast_def.h Sun Jul 01 20:15:56 2007 +0900
@@ -35,7 +35,7 @@ D_CAST(FLOAT, "float", "vm_float_t", "
D_CAST(FLOAT, "float", "vm_float_t", "F", D_FNC | D_VAR | D_PRM, 1, 1)
D_CAST(HANDLE, "handle", "vm_handle_t", "H", D_FNC | D_VAR | D_PRM, 1, 1)
D_CAST(INT, "int", "vm_int_t", "I", D_FNC | D_VAR | D_PRM, 1, 1)
-D_CAST(INTERRUPT, "interrupt", "vm_taddr_t", "T", D_FNC | D_PRM, 1, 1)
+D_CAST(INTERRUPT, "", "void", NULL, D_FNC, 0, 0)
D_CAST(STRING, "string", "char const*", "S", D_VAR | D_PRM, 1, 1)
D_CAST(TRIGGER, "trigger", NULL, NULL, D_FNC, 1, 1)
D_CAST(THREAD, "thread", "vm_taddr_t", "T", D_FNC | D_PRM, 1, 1)
--- a/tool/src/cscript/code/comp.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/comp.cc Sun Jul 01 20:15:56 2007 +0900
@@ -81,10 +81,12 @@ public:
SymbolSyscall const* defineSyscall(vm_dword_t sysno, std::string const& id, Cast cast, VariableInfoList const& param_list);
SymbolSyscall const* findSyscall(std::string const& id) const;
- SymbolFunction* beginFunction(std::string const& id, Cast cast, VariableInfoList const& param_list);
+ SymbolFunction* beginFunction(std::string const& id, Cast cast, VariableInfoList const& param_list = VariableInfoList());
+ SymbolFunction* beginInterrupt(std::string const& id, vm_intrno_t intr_no);
SymbolFunction const* getCurrentFunction() { return m_func_sym; }
- void endFunction(SymbolFunction const* sym_func);
+ void endFunction(SymbolFunction const* func_sym);
SymbolFunction const* findFunction(std::string const& id) const;
+ void endInterrupt(SymbolFunction const* func_sym);
SymbolFunctionBase const* findFunctionBase(std::string const& id) const;
@@ -107,15 +109,21 @@ public:
// IDumpObject
virtual vm_taddr_t getCodeSize() const { return m_code.getSize(); }
virtual vm_tword_t const* getCode() const { return m_code.getCode(); }
+ virtual size_t getInterruptSize() const { return m_intr_map.size(); }
+ virtual void getInterrupt(std::pair<vm_intrno_t, vm_taddr_t>* p, size_t len) const;
virtual size_t getLiteralSize() const { return m_literal_tbl.size(); }
virtual char const* getLiteral(vm_literal_t no) const;
virtual size_t getStaticDataSize() const { return m_global_var_addr; }
virtual size_t getInitDataSize() const;
virtual std::pair<vm_daddr_t, vm_dsize_t> getInitData(size_t index) const;
+
private:
// シンボルテーブル
SymbolTable m_sym_tbl;
+ // 割り込みテーブル
+ typedef std::map<vm_intrno_t, vm_taddr_t> IntrMap;
+ IntrMap m_intr_map;
// 文字列リテラルテーブル
typedef std::vector<boost::shared_ptr<Literal> > LiteralTable;
LiteralTable m_literal_tbl;
@@ -173,6 +181,14 @@ std::pair<vm_daddr_t, vm_dsize_t> Comp::
{
assert(index < m_global_var_data.size());
return m_global_var_data[index];
+}
+
+void Comp::Impl::getInterrupt(std::pair<vm_intrno_t, vm_taddr_t>* p, size_t len) const
+{
+ assert(p != NULL);
+ for (IntrMap::const_iterator i = m_intr_map.begin(); i != m_intr_map.end() && len-- > 0; ++i)
+ *p++ = std::make_pair(i->first, i->second);
+
}
void Comp::Impl::setInitData(vm_daddr_t addr, vm_dword_t word)
@@ -456,6 +472,18 @@ SymbolFunction* Comp::Impl::beginFunctio
return m_func_sym;
}
+SymbolFunction* Comp::Impl::beginInterrupt(std::string const& id, vm_intrno_t intr_no)
+{
+ SymbolFunction* func_sym = beginFunction(id, Cast::INTERRUPT);
+
+ if (m_intr_map.find(intr_no) != m_intr_map.end())
+ throw std::runtime_error((boost::format("intrrupt duplicated [%s, %d]") % id % intr_no).str());
+
+ vm_taddr_t intr_addr = func_sym->getAddr();
+ m_intr_map[intr_no] = intr_addr;
+ return func_sym;
+}
+
void Comp::Impl::endFunction(SymbolFunction const* func_sym)
{
assert(m_func_sym != NULL);
@@ -467,6 +495,11 @@ void Comp::Impl::endFunction(SymbolFunct
m_code.genCodeRETURN(func_sym->getParamSize());
m_code.backpatchENTER(func_sym->getAddrEnter(), func_sym->getLocalVarSize());
m_func_sym = NULL;
+}
+
+void Comp::Impl::endInterrupt(SymbolFunction const* func_sym)
+{
+ endFunction(func_sym);
}
SymbolFunction const* Comp::Impl::findFunction(std::string const& id) const
@@ -581,6 +614,11 @@ SymbolFunction* Comp::beginFunction(std:
return m_impl->beginFunction(id, cast, param_list);
}
+SymbolFunction* Comp::beginInterrupt(std::string const& id, vm_intrno_t intr_no)
+{
+ return m_impl->beginInterrupt(id, intr_no);
+}
+
SymbolFunction const* Comp::getCurrentFunction() const
{
return m_impl->getCurrentFunction();
@@ -589,6 +627,11 @@ void Comp::endFunction(SymbolFunction co
void Comp::endFunction(SymbolFunction const* func_sym)
{
m_impl->endFunction(func_sym);
+}
+
+void Comp::endInterrupt(SymbolFunction const* func_sym)
+{
+ m_impl->endInterrupt(func_sym);
}
SymbolFunction const* Comp::findFunction(std::string const& id) const
--- a/tool/src/cscript/code/comp.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/comp.h Sun Jul 01 20:15:56 2007 +0900
@@ -122,8 +122,11 @@ public:
SymbolFunction* beginFunction(std::string const& id, Cast cast, VariableInfoList const& param_list);
SymbolFunction const* getCurrentFunction() const;
- void endFunction(SymbolFunction const* sym_func);
+ void endFunction(SymbolFunction const* func_sym);
SymbolFunction const* findFunction(std::string const& id) const;
+
+ SymbolFunction* beginInterrupt(std::string const& id, vm_intrno_t intr_no);
+ void endInterrupt(SymbolFunction const* func_sym);
SymbolFunctionBase const* findFunctionBase(std::string const& id) const;
--- a/tool/src/cscript/code/cscds_main.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/cscds_main.cc Sun Jul 01 20:15:56 2007 +0900
@@ -30,6 +30,8 @@
#include "vm_loader.h"
static char const* s_progname;
+static char const* const LABEL_ENTRY[] = { "entry", "entries" };
+static char const* const LABEL_WORD[] = { "word", "words" };
static void usage()
{
@@ -69,8 +71,18 @@ int main(int argc, char** argv)
std::cout << boost::format("%04x:\t%s") % i % inst_table.toString(p[i]) << "\n";
std::cout << "\n";
- static char const* const LABEL_ENTRY[] = { "entry", "entries" };
- static char const* const LABEL_WORD[] = { "word", "words" };
+ // INTERRUPT
+ size_t interrupt_size = loader.getInterruptSize();
+ std::cout <<
+ boost::format("INTERRUPT DUMP (%d %s)") % interrupt_size % LABEL_ENTRY[interrupt_size > 1] <<
+ "\n";
+
+ std::cout << boost::format("%-8s %-8s\n") % "intr_no" % "intr_addr";
+ for (size_t i = 0; i < interrupt_size; ++i) {
+ std::pair<CScript::vm_intrno_t, CScript::vm_taddr_t> d = loader.getInterrupt(i);
+ std::cout << boost::format("%08x %08x\n") % d.first % d.second;
+ }
+ std::cout << "\n";
// STATIC_DATA
size_t static_data_count = loader.getStaticDataSize();
--- a/tool/src/cscript/code/cscvm_main.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/cscvm_main.cc Sun Jul 01 20:15:56 2007 +0900
@@ -31,10 +31,14 @@
#include "vm_sys_ud.h"
#define CSCR_HANDLE_TEST
+#define CSCR_INTRRUPT_TEST
#ifdef CSCR_HANDLE_TEST
#include "scr_sys_test_pl.h"
#endif // CSCR_HANDLE_TEST
+#ifdef CSCR_INTRRUPT_TEST
+#include "../sample/intr.sch"
+#endif // CSCR_INTRRUPT_TEST
CSCRIPT_NAMESPACE_USING
@@ -85,11 +89,18 @@ int main(int argc, char** argv)
// CODE
vm.setCode(loader.getCode(), loader.getCodeSize());
+ // INTERRUPT
+ size_t interrupt_size = loader.getInterruptSize();
+ for (size_t i = 0; i < interrupt_size; ++i) {
+ std::pair<vm_intrno_t, vm_taddr_t> d = loader.getInterrupt(i);
+ vm.setInterrupt(d.first, d.second);
+ }
+
// STATIC_DATA
vm.setStaticDataSize(loader.getStaticDataSize());
size_t static_data_max = loader.getInitDataSize();
for (size_t i = 0; i < static_data_max; ++i) {
- std::pair<CScript::vm_daddr_t, CScript::vm_dword_t> const& d = loader.getInitData(i);
+ std::pair<CScript::vm_daddr_t, CScript::vm_dword_t> d = loader.getInitData(i);
vm.setStaticData(d.first, d.second);
}
@@ -103,6 +114,10 @@ int main(int argc, char** argv)
PlayerImpl player;
vm.setScrArgH(0, &player);
#endif // CSCR_HANDLE_TEST
+#ifdef CSCR_INTRRUPT_TEST
+ vm.intr(SAMPLE_INTR_1);
+ vm.intr(SAMPLE_INTR_2);
+#endif
int run_count = 0;
while (vm.run())
--- a/tool/src/cscript/code/dump.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/dump.cc Sun Jul 01 20:15:56 2007 +0900
@@ -44,6 +44,7 @@ private:
bool _dumpCode(std::ostream& os, IDumpObject const& ctx);
bool _dumpLiteral(std::ostream& os, IDumpObject const& ctx);
bool _dumpStaticData(std::ostream& os, IDumpObject const& ctx);
+ bool _dumpInterrupt(std::ostream& os, IDumpObject const& ctx);
bool _dumpTrailer(std::ostream& os);
size_t _align(size_t size)
@@ -59,6 +60,7 @@ bool Dumper::Impl::dump(std::ostream& os
_dumpHeader(os)
&& _dumpCode(os, ctx)
&& _dumpStaticData(os, ctx)
+ && _dumpInterrupt(os, ctx)
&& _dumpLiteral(os, ctx)
&& _dumpTrailer(os);
}
@@ -187,6 +189,55 @@ bool Dumper::Impl::_dumpStaticData(std::
return true;
}
+bool Dumper::Impl::_dumpInterrupt(std::ostream& os, IDumpObject const& ctx)
+{
+ // InterruptData
+ File::Interrupt intr_data;
+ intr_data.count = ctx.getInterruptSize();
+ if (intr_data.count == 0)
+ return true;
+
+ std::vector<File::Interrupt::Node> buf(intr_data.count);
+ memset(&buf[0], 0, sizeof(buf[0]) * buf.size());
+ ctx.getInterrupt(&buf[0], buf.size());
+
+ //
+ boost::uint32_t size_raw = sizeof(intr_data) + sizeof(buf[0]) * buf.size();
+ boost::uint32_t size_aligned = _align(size_raw);
+ boost::uint32_t size_padding = size_aligned - size_raw;
+
+ File::crc crc;
+ crc.process_bytes(&intr_data, sizeof(intr_data));
+ crc.process_bytes(&buf[0], sizeof(buf[0]) * buf.size());
+ for (boost::uint32_t i = 0; i < size_padding; ++i)
+ crc.process_byte(0);
+
+ // Info
+ File::Info info;
+ memset(&info, 0, sizeof(info));
+ info.section = File::SECTION_INTERRUPT;
+ info.size = size_aligned;
+ info.crc = crc.checksum();
+
+ //
+ os.write(reinterpret_cast<char const*>(&info), sizeof(info));
+ if (os.fail())
+ return false;
+ os.write(reinterpret_cast<char const*>(&intr_data), sizeof(intr_data));
+ if (os.fail())
+ return false;
+ os.write(reinterpret_cast<char const*>(&buf[0]), sizeof(buf[0]) * buf.size());
+ if (os.fail())
+ return false;
+ for (boost::uint32_t i = 0; i < size_padding; ++i) {
+ os << '\0';
+ if (os.fail())
+ return false;
+ }
+
+ return true;
+}
+
bool Dumper::Impl::_dumpLiteral(std::ostream& os, IDumpObject const& ctx)
{
vm_literal_t lit_count = ctx.getLiteralSize();
--- a/tool/src/cscript/code/dump.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/dump.h Sun Jul 01 20:15:56 2007 +0900
@@ -34,6 +34,8 @@ struct IDumpObject
virtual ~IDumpObject() {}
virtual vm_taddr_t getCodeSize() const = 0;
virtual vm_tword_t const* getCode() const = 0;
+ virtual size_t getInterruptSize() const = 0;
+ virtual void getInterrupt(std::pair<vm_intrno_t, vm_taddr_t>* p, size_t len) const = 0;
virtual size_t getLiteralSize() const = 0;
virtual char const* getLiteral(vm_literal_t no) const = 0;
virtual size_t getStaticDataSize() const = 0;
--- a/tool/src/cscript/code/file.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/file.h Sun Jul 01 20:15:56 2007 +0900
@@ -46,9 +46,9 @@ namespace File
{
SECTION_ERROR, // 使用不可
SECTION_CODE, // 必須
+ SECTION_INTERRUPT, // オプション
+ SECTION_TRIGGER, // オプション
SECTION_STATIC_DATA, // オプション
- SECTION_TRIGGER, // オプション
- SECTION_INTERRUPT, // オプション
SECTION_LITERAL_DATA, // オプション
SECTION_LITERAL_PTR, // オプション
SECTION_TRAILER, // 必須
@@ -96,9 +96,29 @@ namespace File
// p -> +-------------------+
// | File::Info |
// q -> +-------------------+ ┬
+ // | File::Interrupt | p->size (bytes)
+ // +-------------------+ │ ┬
+ // | data[] | │ q->count (double words)
+ // | | │ │
+ // | | │ │
+ // +-------------------+ │ ┴
+ // | _padding | │
+ // +-------------------+ ┴
+ struct Interrupt
+ {
+ typedef std::pair<vm_intrno_t, vm_taddr_t> Node;
+
+ boost::uint32_t count;
+ boost::uint8_t _padding[12];
+ Node data[];
+ };
+
+ // p -> +-------------------+
+ // | File::Info |
+ // q -> +-------------------+ ┬
// | File::StaticData | p->size (bytes)
// +-------------------+ │ ┬
- // | data[] | │ q->init_count (double words)
+ // | init_data[] | │ q->init_count (double words)
// | | │ │
// | | │ │
// +-------------------+ │ ┴
@@ -131,7 +151,7 @@ namespace File
struct LiteralData
{
boost::uint16_t count;
- boost::uint8_t _padding[12];
+ boost::uint8_t _padding[14];
char data[];
};
--- a/tool/src/cscript/code/lex.l Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/lex.l Sun Jul 01 20:15:56 2007 +0900
@@ -148,8 +148,8 @@ Cast const* LexHolder::Impl::_getCast(ch
{ NULL, Cast::ERROR, 0U },
};
- for (CastDB const* p = &db[0]; p->name != NULL; ++p)
- if (strcmp(s, p->name) == 0) {
+ for (CastDB const* p = &db[0]; p->cast != Cast::ERROR; ++p)
+ if (p->name[0] != '\0' && strcmp(s, p->name) == 0) {
if (p->use_mask == 0U)
yyerror((std::string("unsupported cast[") + p->name + "]").c_str());
return &p->cast;
--- a/tool/src/cscript/code/parser.y Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/parser.y Sun Jul 01 20:15:56 2007 +0900
@@ -159,6 +159,7 @@ node_root_element:
node_root_element:
node_system_decl
| node_function
+ | node_interrupt
| node_global_var_decl
| node_typedef_decl
;
@@ -389,6 +390,29 @@ node_typedef_opt:
node_typedef_opt:
/* empty */
| '[' TOK_ID ',' TOK_LITERAL ']'
+ ;
+
+node_interrupt:
+ TOK_INTERRUPT '[' node_intr_no ']' TOK_ID '(' ')' '{' {
+ vm_int_t intr_no = boost::get<vm_int_t>($3);
+ std::string const& func_id = boost::get<std::string const&>($5);
+ $$ = p_comp->beginInterrupt(func_id, intr_no);
+ } node_block {
+ p_comp->endInterrupt(boost::get<SymbolFunction*>($9));
+ }
+ '}'
+ ;
+
+node_intr_no:
+ node_const_expression {
+ ConstInfo const& info = boost::get<ConstInfo const&>($1);
+ if (info.cast != Cast::INT) {
+ yyerror("cast mismatch");
+ break;
+ }
+ vm_intrno_t intr_no = boost::get<vm_intrno_t>(info.val);
+ $$ = intr_no;
+ }
;
node_function:
--- a/tool/src/cscript/code/vm.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/vm.cc Sun Jul 01 20:15:56 2007 +0900
@@ -97,6 +97,7 @@ class VMThread
{
public:
typedef vm_int_t Id;
+ static Id const IntrId = -1;
typedef std::set<Id> TChildIdList;
struct ICtxVirtualMachine
@@ -187,6 +188,7 @@ public:
Impl(Param const& param);
virtual ~Impl();
void setCode(vm_tword_t const* code, size_t size);
+ void setInterrupt(vm_intrno_t intr_no, vm_taddr_t intr_addr);
void setStaticDataSize(vm_dsize_t size);
void setStaticData(vm_daddr_t daddr, vm_dword_t dword);
void addLiteral(char const* s);
@@ -195,6 +197,7 @@ public:
void setScrArgH(int idx, vm_handle_t h);
bool run();
+ bool intr(vm_intrno_t intr_no);
STATE getState() const { return m_common_reg.sw; }
protected:
@@ -281,6 +284,10 @@ private:
VirtualMachine::Impl& m_vm_impl;
};
friend struct VMThreadResHolder;
+
+ // 割り込みマップ
+ typedef std::map<vm_intrno_t, vm_taddr_t> VMIntrMap;
+ VMIntrMap m_intr_map;
u m_sys_args[CSCR_VM_SYSARG_MAX]; // C++側からVM起動時に渡されるパラメタ
VMThread::Id m_thread_id_next;
@@ -490,6 +497,13 @@ void VirtualMachine::Impl::setCode(vm_tw
m_code = code;
m_code_size = size;
+}
+
+void VirtualMachine::Impl::setInterrupt(vm_intrno_t intr_no, vm_taddr_t intr_addr)
+{
+ if (m_intr_map.find(intr_no) != m_intr_map.end())
+ CSCR_VM_DPRINTF("sysIntrRegister : overreide intr : %d\n", intr_no);
+ m_intr_map[intr_no] = intr_addr;
}
void VirtualMachine::Impl::setStaticDataSize(vm_dsize_t size)
@@ -731,6 +745,52 @@ bool VirtualMachine::Impl::run()
++m_common_reg.run;
return m_common_reg.sw == STATE_OK;
+}
+
+bool VirtualMachine::Impl::intr(vm_intrno_t intr_no)
+{
+ if (m_common_reg.sw != STATE_OK) {
+ CSCR_VM_DPRINTF("intr : invalid vm state : %d\n", m_common_reg.sw);
+ return false;
+ }
+
+ VMIntrMap::const_iterator i = m_intr_map.find(intr_no);
+ if (i == m_intr_map.end()) {
+ CSCR_VM_DPRINTF("intr : intr_no not registerd [%d]\n", intr_no);
+ return false;
+ }
+ vm_taddr_t intr_addr = i->second;
+
+ VMThread thread(0, VMThread::IntrId);
+ thread.thr_stack.resize(VM_STACK_SIZE);
+
+ VMThreadResHolder holder(*this, thread);
+ VMThread::Regs& regs = _get_thread_regs();
+ regs.pc = intr_addr; // intr_addr
+ _push(1); // addr of INST_halt
+ assert(CSCR_VM_TWORD_OPCODE_GET(m_code[1]) == INST_halt);
+
+ for (int loop_count = 0; !regs.halt && regs.sleep == 0; ++m_common_reg.tick) {
+ if (0 < VM_LOOP_COUNT_MAX && VM_LOOP_COUNT_MAX < loop_count++) {
+ m_common_reg.sw = STATE_INFINITE_LOOP;
+ return false;
+ }
+ if (m_code_size <= regs.pc) {
+ m_common_reg.sw = STATE_CODE_FAULT;
+ return false;
+ }
+ _exec1(m_code[regs.pc++]);
+ if (m_common_reg.sw != STATE_OK)
+ return false;
+ }
+
+ if (_get_thread_regs().sleep > 0) {
+ // 割り込み処理では sysSleep() 呼び出し不可
+ m_common_reg.sw = STATE_INVALID_SYSCALL;
+ return false;
+ }
+
+ return true;
}
vm_int_t VirtualMachine::Impl::_opr_int(vm_tword_oprand_t oprand)
@@ -1105,6 +1165,11 @@ void VirtualMachine::setCode(vm_tword_t
m_impl->setCode(code, size);
}
+void VirtualMachine::setInterrupt(vm_intrno_t intr_no, vm_taddr_t intr_addr)
+{
+ m_impl->setInterrupt(intr_no, intr_addr);
+}
+
void VirtualMachine::setStaticDataSize(vm_dsize_t size)
{
m_impl->setStaticDataSize(size);
@@ -1140,6 +1205,11 @@ bool VirtualMachine::run()
return m_impl->run();
}
+bool VirtualMachine::intr(vm_intrno_t intr_no)
+{
+ return m_impl->intr(intr_no);
+}
+
VirtualMachine::STATE VirtualMachine::getState() const
{
return m_impl->getState();
--- a/tool/src/cscript/code/vm.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/vm.h Sun Jul 01 20:15:56 2007 +0900
@@ -67,6 +67,7 @@ public:
~VirtualMachine();
void setCode(vm_tword_t const* code, size_t size);
+ void setInterrupt(vm_intrno_t intr_no, vm_taddr_t intr_addr);
void setStaticDataSize(vm_dsize_t size);
void setStaticData(vm_daddr_t daddr, vm_dword_t dword);
void addLiteral(char const* s);
@@ -113,6 +114,14 @@ public:
*/
bool run();
+ /*
+ * 仮想マシンに割り込みをかける
+ *
+ * @param intr_no
+ * 割り込み番号
+ */
+ bool intr(vm_intrno_t intr_no);
+
/**
* 仮想マシン状態を取得する
*/
--- a/tool/src/cscript/code/vm_cast.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/vm_cast.h Sun Jul 01 20:15:56 2007 +0900
@@ -62,6 +62,7 @@ typedef float vm_float_t;
typedef float vm_float_t;
typedef void* vm_handle_t;
typedef boost::uint16_t vm_sysno_t;
+typedef boost::int32_t vm_intrno_t;
#define CSCR_VM_TWORD_SYSCALL_SYSNO_GET(x) static_cast<vm_sysno_t>(((x) & 0x0000ffff))
#define CSCR_VM_TWORD_SYSCALL_ARGSIZE_GET(x) (((x) >> 16) & 0xff)
#define CSCR_VM_SYSCALL_ARGSIZE_MAX (255)
--- a/tool/src/cscript/code/vm_loader.cc Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/vm_loader.cc Sun Jul 01 20:15:56 2007 +0900
@@ -40,6 +40,7 @@ CSCRIPT_NAMESPACE_BEGIN
VirtualMachineLoader::VirtualMachineLoader()
: m_code(NULL)
+ , m_interrupt(NULL)
, m_static_data(NULL)
, m_literal_ptr(NULL)
, m_literal_data(NULL)
@@ -64,6 +65,14 @@ bool VirtualMachineLoader::load(void con
return false;
}
if (!_loadCode(pInfo, &len))
+ return false;
+ break;
+ case File::SECTION_INTERRUPT:
+ if (m_interrupt != NULL) {
+ fprintf(stderr, "Duplicate interrupt section\n");
+ return false;
+ }
+ if (!_loadInterrupt(pInfo, &len))
return false;
break;
case File::SECTION_STATIC_DATA:
@@ -168,6 +177,11 @@ bool VirtualMachineLoader::_loadCode(Fil
return _loadSection(&m_code, p, plen, File::SECTION_CODE);
}
+bool VirtualMachineLoader::_loadInterrupt(File::Info const* p, size_t* plen)
+{
+ return _loadSection(&m_interrupt, p, plen, File::SECTION_INTERRUPT);
+}
+
bool VirtualMachineLoader::_loadStaticData(File::Info const* p, size_t* plen)
{
return _loadSection(&m_static_data, p, plen, File::SECTION_STATIC_DATA);
@@ -193,6 +207,18 @@ vm_psize_t VirtualMachineLoader::getCode
{
assert(m_code != NULL);
return m_code->count;
+}
+
+size_t VirtualMachineLoader::getInterruptSize() const
+{
+ return m_interrupt == NULL ? 0 : m_interrupt->count;
+}
+
+std::pair<vm_intrno_t, vm_taddr_t> VirtualMachineLoader::getInterrupt(size_t index) const
+{
+ assert(m_interrupt != NULL);
+ assert(index < m_interrupt->count);
+ return m_interrupt->data[index];
}
size_t VirtualMachineLoader::getStaticDataSize() const
--- a/tool/src/cscript/code/vm_loader.h Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/code/vm_loader.h Sun Jul 01 20:15:56 2007 +0900
@@ -38,6 +38,8 @@ public:
vm_tword_t const* getCode() const;
vm_psize_t getCodeSize() const;
+ size_t getInterruptSize() const;
+ std::pair<vm_intrno_t, vm_taddr_t> getInterrupt(size_t index) const;
size_t getStaticDataSize() const;
size_t getInitDataSize() const;
std::pair<vm_daddr_t, vm_dword_t> getInitData(size_t index) const;
@@ -46,12 +48,14 @@ public:
private:
File::Code const* m_code;
+ File::Interrupt const* m_interrupt;
File::StaticData const* m_static_data;
File::LiteralPtr const* m_literal_ptr;
File::LiteralData const* m_literal_data;
bool _loadHeader(File::Header const* p, size_t* plen);
bool _loadCode(File::Info const* p, size_t* plen);
+ bool _loadInterrupt(File::Info const* p, size_t* plen);
bool _loadStaticData(File::Info const* p, size_t* plen);
bool _loadLiteralData(File::Info const* p, size_t* plen);
bool _loadLiteralPtr(File::Info const* p, size_t* plen);
--- a/tool/src/cscript/cscript/cscript.sch Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/cscript/cscript.sch Sun Jul 01 20:15:56 2007 +0900
@@ -45,10 +45,6 @@
#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_THREAD_END (63)
#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_THREAD_COUNT (CSCR_VM_SYSNO_SYSFUNC_INTERNAL_THREAD_END - CSCR_VM_SYSNO_SYSFUNC_INTERNAL_THREAD_BEGIN + 1)
-#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_BEGIN (CSCR_VM_SYSNO_SYSFUNC_INTERNAL_THREAD_END + 1)
-#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_END (80)
-#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_COUNT (CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_END - CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_BEGIN + 1)
-
#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_DEBUG_BEGIN (112)
#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_DEBUG_END (127)
#define CSCR_VM_SYSNO_SYSFUNC_INTERNAL_DEBUG_COUNT (CSCR_VM_SYSNO_SYSFUNC_INTERNAL_DEBUG_END - CSCR_VM_SYSNO_SYSFUNC_INTERNAL_DEBUG_BEGIN + 1)
--- a/tool/src/cscript/cscript/system.sch Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/cscript/system.sch Sun Jul 01 20:15:56 2007 +0900
@@ -106,11 +106,6 @@ __system[] void sysThreadWaitAll();
__system[] void sysThreadWaitAll();
// -------------------------------------------------------------------
-// 割り込み処理
-// -------------------------------------------------------------------
-__system[CSCR_VM_SYSNO_SYSFUNC_INTERNAL_INTERRUPT_BEGIN] void sysIntrRegister(sys_intr_t intrno, interrupt intr_main);
-
-// -------------------------------------------------------------------
// デバッグ用システム関数
// -------------------------------------------------------------------
#ifndef NDEBUG
--- a/tool/src/cscript/m4/keyword.m4 Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/m4/keyword.m4 Sun Jul 01 20:15:56 2007 +0900
@@ -22,29 +22,30 @@ dnl FROM, OUT OF OR IN CONNECTION WITH T
dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
dnl DEALINGS IN THE SOFTWARE.
dnl
-M4_KEYWORD("__system", `TOK_SYSTEM')
-M4_KEYWORD("auto", `TOK_AUTO')
-M4_KEYWORD("break", `TOK_BREAK')
-M4_KEYWORD("case", `TOK_CASE')
-M4_KEYWORD("const", `TOK_CONST')
-M4_KEYWORD("continue", `TOK_CONTINUE')
-M4_KEYWORD("default", `TOK_DEFAULT')
-M4_KEYWORD("do", `TOK_DO')
-M4_KEYWORD("else", `TOK_ELSE')
-M4_KEYWORD("enum", `TOK_ENUM')
-M4_KEYWORD("extern", `TOK_EXTERN')
-M4_KEYWORD("for", `TOK_FOR')
-M4_KEYWORD("goto", `TOK_GOTO')
-M4_KEYWORD("if", `TOK_IF')
-M4_KEYWORD("register", `TOK_REGISTER')
-M4_KEYWORD("return", `TOK_RETURN')
-M4_KEYWORD("signed", `TOK_SIGNED')
-M4_KEYWORD("sizeof", `TOK_SIZEOF')
-M4_KEYWORD("static", `TOK_STATIC')
-M4_KEYWORD("struct", `TOK_STRUCT')
-M4_KEYWORD("switch", `TOK_SWITCH')
-M4_KEYWORD("typedef", `TOK_TYPEDEF')
-M4_KEYWORD("union", `TOK_UNION')
-M4_KEYWORD("unsigned", `TOK_UNSIGNED')
-M4_KEYWORD("volatile", `TOK_VOLATILE')
-M4_KEYWORD("while", `TOK_WHILE')
+M4_KEYWORD("__system", `TOK_SYSTEM')
+M4_KEYWORD("__interrupt", `TOK_INTERRUPT')
+M4_KEYWORD("auto", `TOK_AUTO')
+M4_KEYWORD("break", `TOK_BREAK')
+M4_KEYWORD("case", `TOK_CASE')
+M4_KEYWORD("const", `TOK_CONST')
+M4_KEYWORD("continue", `TOK_CONTINUE')
+M4_KEYWORD("default", `TOK_DEFAULT')
+M4_KEYWORD("do", `TOK_DO')
+M4_KEYWORD("else", `TOK_ELSE')
+M4_KEYWORD("enum", `TOK_ENUM')
+M4_KEYWORD("extern", `TOK_EXTERN')
+M4_KEYWORD("for", `TOK_FOR')
+M4_KEYWORD("goto", `TOK_GOTO')
+M4_KEYWORD("if", `TOK_IF')
+M4_KEYWORD("register", `TOK_REGISTER')
+M4_KEYWORD("return", `TOK_RETURN')
+M4_KEYWORD("signed", `TOK_SIGNED')
+M4_KEYWORD("sizeof", `TOK_SIZEOF')
+M4_KEYWORD("static", `TOK_STATIC')
+M4_KEYWORD("struct", `TOK_STRUCT')
+M4_KEYWORD("switch", `TOK_SWITCH')
+M4_KEYWORD("typedef", `TOK_TYPEDEF')
+M4_KEYWORD("union", `TOK_UNION')
+M4_KEYWORD("unsigned", `TOK_UNSIGNED')
+M4_KEYWORD("volatile", `TOK_VOLATILE')
+M4_KEYWORD("while", `TOK_WHILE')
--- a/tool/src/cscript/mk/cscript.mak Mon Jun 25 17:01:05 2007 +0900
+++ b/tool/src/cscript/mk/cscript.mak Sun Jul 01 20:15:56 2007 +0900
@@ -10,7 +10,7 @@ CSCRCFLAGS=
CSCRCFLAGS=
CPP= cpp
-CPPFLAGS= -nostdinc -undef -I ../cscript
+CPPFLAGS= -nostdinc -undef -I ../cscript -DCSCRIPT
SRCS= $(notdir $(wildcard *.scs))
DEPS= $(addsuffix .scd,$(basename $(SRCS)))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/src/cscript/sample/intr.sch Sun Jul 01 20:15:56 2007 +0900
@@ -0,0 +1,16 @@
+/*
+ * 割り込みテスト
+ * $Id: for.scs 444 2007-06-04 23:03:03Z issei $
+ */
+
+#ifndef SAMPLE_INTR_SCH__INCLUDED
+#define SAMPLE_INTR_SCH__INCLUDED
+
+#define SAMPLE_INTR_1 (1)
+#define SAMPLE_INTR_2 (2)
+
+#endif // SAMPLE_INTR_SCH__INCLUDED
+
+// vim: syntax=c
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/src/cscript/sample/intr.scs Sun Jul 01 20:15:56 2007 +0900
@@ -0,0 +1,24 @@
+/*
+ * 割り込みテスト
+ * $Id: for.scs 444 2007-06-04 23:03:03Z issei $
+ */
+
+#include <system.sch>
+#include <stdfunc.sch>
+
+__interrupt[1] testIntr1()
+{
+ sysPrintS("intr 1\n");
+}
+
+__interrupt[2] testIntr2()
+{
+ sysPrintS("intr 2\n");
+}
+
+void main()
+{
+}
+
+// vim: syntax=c
+