|
@@ -1,10 +1,21 @@
|
|
|
#include "activation.hpp"
|
|
|
#include "value.hpp"
|
|
|
+#include "inter.hpp"
|
|
|
#include "init.hpp"
|
|
|
+#include "msg.hpp"
|
|
|
+#include "var.hpp"
|
|
|
+#include "code.hpp"
|
|
|
|
|
|
using namespace aFuncore;
|
|
|
using namespace aFuntool;
|
|
|
|
|
|
+/**
|
|
|
+ * 创建基本Activation
|
|
|
+ * 若上层Activation已到结尾则尾调用优化
|
|
|
+ * 自动继承上层VarList和UpMessage
|
|
|
+ * 自动压入inter
|
|
|
+ * @param inter_
|
|
|
+ */
|
|
|
Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
|
|
|
Activation *prev_ = inter->getActivation();
|
|
|
if (prev_ != nullptr && prev_->onTail()) {
|
|
@@ -29,6 +40,11 @@ Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
|
|
|
inter->pushActivation(this);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 析构Activation
|
|
|
+ * 注意: 不会自动从inter中弹出
|
|
|
+ * 释放Varlist并且将DownMessage压入上层
|
|
|
+ */
|
|
|
Activation::~Activation(){
|
|
|
if (varlist != nullptr && old_varlist != nullptr)
|
|
|
varlist->disconnect(old_varlist);
|
|
@@ -38,6 +54,10 @@ Activation::~Activation(){
|
|
|
delete down;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 运行代码
|
|
|
+ * @param code
|
|
|
+ */
|
|
|
void Activation::runCode(Code *code){
|
|
|
auto code_type = code->getType();
|
|
|
if (code_type == code_start) { // start 不处理 msg
|
|
@@ -53,6 +73,7 @@ void Activation::runCode(Code *code){
|
|
|
Object *obj = nullptr;
|
|
|
if (varlist != nullptr)
|
|
|
obj = varlist->findObject(code->getElement());
|
|
|
+ trackLog(aFunCoreLogger, "Find Var %s -> %p", code->getElement(), obj);
|
|
|
if (obj != nullptr)
|
|
|
down->pushMessage(new NormalMessage(obj));
|
|
|
}
|
|
@@ -61,8 +82,8 @@ void Activation::runCode(Code *code){
|
|
|
new ExeActivation(code->getSon(), inter);
|
|
|
break;
|
|
|
case block_b:
|
|
|
- break;
|
|
|
case block_c:
|
|
|
+ new FuncActivation(code, inter);
|
|
|
break;
|
|
|
default:
|
|
|
errorLog(aFunCoreLogger, "Error block type.");
|
|
@@ -77,11 +98,11 @@ ActivationStatus ExeActivation::getCode(Code *&code){
|
|
|
return as_end;
|
|
|
|
|
|
if (!first) {
|
|
|
- Message *msg = down->getMessage<NormalMessage>("NORMAL");
|
|
|
- if (msg == nullptr) {
|
|
|
+ auto msg = down->getMessage<NormalMessage>("NORMAL");
|
|
|
+ if (msg == nullptr)
|
|
|
return as_end;
|
|
|
- } else
|
|
|
- msg = down->popMessage("NORMAL");
|
|
|
+ else
|
|
|
+ down->popMessage("NORMAL");
|
|
|
delete msg;
|
|
|
}
|
|
|
|
|
@@ -104,3 +125,66 @@ static void ActivationTopProgress(Message *msg, void *) {
|
|
|
TopActivation::~TopActivation() {
|
|
|
down->forEach<void *>(ActivationTopProgress, nullptr);
|
|
|
}
|
|
|
+
|
|
|
+FuncActivation::~FuncActivation(){
|
|
|
+ delete call_func;
|
|
|
+}
|
|
|
+
|
|
|
+ActivationStatus FuncActivation::getCode(Code *&code){
|
|
|
+ if (on_tail)
|
|
|
+ return as_end;
|
|
|
+
|
|
|
+ if (status == func_first) {
|
|
|
+ status = func_get_func;
|
|
|
+ switch (call->getBlockType()) {
|
|
|
+ case block_c:
|
|
|
+ code = call->getSon();
|
|
|
+ return as_run;
|
|
|
+ case block_b:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ errorLog(aFunCoreLogger, "Error FuncActivation block type");
|
|
|
+ return as_end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status == func_get_func) {
|
|
|
+ status = func_get_arg;
|
|
|
+ auto *msg = down->getMessage<NormalMessage>("NORMAL");
|
|
|
+ if (msg == nullptr)
|
|
|
+ return as_end;
|
|
|
+ else
|
|
|
+ down->popMessage("NORMAL");
|
|
|
+ func = dynamic_cast<Function *>(msg->getObject());
|
|
|
+ delete msg;
|
|
|
+ if (func == nullptr)
|
|
|
+ return as_end;
|
|
|
+
|
|
|
+ call_func = func->getCallFunction(call, inter);
|
|
|
+ acl = call_func->getArgCodeList();
|
|
|
+ acl_begin = acl->begin();
|
|
|
+ acl_end = acl->end();
|
|
|
+ if (acl_begin != acl_end) {
|
|
|
+ code = acl_begin->code;
|
|
|
+ return as_run;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ auto *msg = down->getMessage<NormalMessage>("NORMAL");
|
|
|
+ if (msg == nullptr)
|
|
|
+ return as_end;
|
|
|
+ else
|
|
|
+ down->popMessage("NORMAL");
|
|
|
+
|
|
|
+ acl_begin->ret = msg->getObject();
|
|
|
+ delete msg;
|
|
|
+
|
|
|
+ acl_begin++;
|
|
|
+ if (acl_begin != acl_end) {
|
|
|
+ code = acl_begin->code;
|
|
|
+ return as_run;
|
|
|
+ }
|
|
|
+
|
|
|
+ on_tail = true;
|
|
|
+ return call_func->runFunction();
|
|
|
+}
|