finish caller
Some checks are pending
Nasal Interpreter Test / mac-aarch64 (push) Waiting to run
Nasal Interpreter Test / linux-x86_64 (push) Waiting to run

Signed-off-by: ValKmjolnir <lhk101lhk101@qq.com>
This commit is contained in:
ValKmjolnir
2025-10-24 00:03:43 +08:00
parent f04996201a
commit 72933f4bf6
9 changed files with 3759 additions and 3721 deletions

View File

@@ -159,26 +159,6 @@ std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
return out; return out;
} }
void nas_co::clear() {
if (!ctx.stack) {
return;
}
for (u32 i = 0; i < VM_STACK_DEPTH; ++i) {
ctx.stack[i] = var::nil();
}
ctx.pc = 0;
ctx.localr = nullptr;
ctx.memr = nullptr;
ctx.canary = ctx.stack+VM_STACK_DEPTH-1;
ctx.top = ctx.stack;
ctx.func_top = ctx.func_stack;
ctx.funcr = var::nil();
ctx.upvalr = var::nil();
status = status::suspended;
}
std::ostream& operator<<(std::ostream& out, const nas_co& co) { std::ostream& operator<<(std::ostream& out, const nas_co& co) {
out << "<coroutine at 0x" << std::hex; out << "<coroutine at 0x" << std::hex;
out << reinterpret_cast<u64>(&co) << std::dec << ">"; out << reinterpret_cast<u64>(&co) << std::dec << ">";

View File

@@ -298,6 +298,12 @@ public:
T convert() const { return reinterpret_cast<T>(pointer); } T convert() const { return reinterpret_cast<T>(pointer); }
}; };
struct callsite {
var caller;
u64 file_index = 0;
u64 line = 0;
};
struct context { struct context {
u64 pc = 0; u64 pc = 0;
var* localr = nullptr; var* localr = nullptr;
@@ -309,8 +315,39 @@ struct context {
var* stack = nullptr; var* stack = nullptr;
var* top = nullptr; var* top = nullptr;
var* func_stack = nullptr; callsite* func_stack = nullptr;
var* func_top = nullptr; callsite* func_top = nullptr;
const std::string* files = nullptr;
void ctor() {
stack = new var[VM_STACK_DEPTH];
func_stack = new callsite[VM_STACK_DEPTH];
}
void dtor() {
delete[] stack;
delete[] func_stack;
}
void clear() {
/* set canary and program counter */
pc = 0;
localr = nullptr;
memr = nullptr;
funcr = var::nil();
upvalr = var::nil();
/* set canary = stack[VM_STACK_DEPTH-1] */
canary = stack + VM_STACK_DEPTH - 1;
/* nothing is on stack */
top = stack;
func_top = func_stack - 1;
/* clear main stack */
for (u32 i = 0; i < VM_STACK_DEPTH; ++i) {
stack[i] = var::nil();
}
}
}; };
struct nas_co { struct nas_co {
@@ -323,16 +360,9 @@ struct nas_co {
context ctx; context ctx;
status status; status status;
nas_co() { nas_co() { ctx.ctor(); }
ctx.stack = new var[VM_STACK_DEPTH]; ~nas_co() { ctx.dtor(); }
ctx.func_stack = new var[VM_STACK_DEPTH]; void clear() { ctx.clear(); status = status::suspended; }
clear();
}
~nas_co() {
delete[] ctx.stack;
delete[] ctx.func_stack;
}
void clear();
friend std::ostream& operator<<(std::ostream&, const nas_co&); friend std::ostream& operator<<(std::ostream&, const nas_co&);
}; };

View File

@@ -45,23 +45,11 @@ void vm::vm_init_enrty(const std::vector<std::string>& strs,
} }
void vm::context_and_global_init() { void vm::context_and_global_init() {
/* set canary and program counter */ /* clear context status */
ctx.pc = 0; ctx.clear();
ctx.localr = nullptr;
ctx.memr = nullptr;
ctx.funcr = nil;
ctx.upvalr = nil;
/* set canary = stack[VM_STACK_DEPTH-1] */
ctx.canary = ctx.stack+VM_STACK_DEPTH-1;
/* nothing is on stack */
ctx.top = ctx.stack - 1;
ctx.func_top = ctx.func_stack - 1;
/* clear main stack and global */ /* clear main stack and global */
for (u32 i = 0; i < VM_STACK_DEPTH; ++i) { for (u32 i = 0; i < VM_STACK_DEPTH; ++i) {
ctx.stack[i] = nil;
global[i] = nil; global[i] = nil;
} }
} }

View File

@@ -287,13 +287,11 @@ public:
/* constructor of vm instance */ /* constructor of vm instance */
vm() { vm() {
ctx.stack = new var[VM_STACK_DEPTH]; ctx.ctor();
ctx.func_stack = new var[VM_STACK_DEPTH];
global = new var[VM_STACK_DEPTH]; global = new var[VM_STACK_DEPTH];
} }
~vm() { ~vm() {
delete[] ctx.stack; ctx.dtor();
delete[] ctx.func_stack;
delete[] global; delete[] global;
} }
@@ -902,7 +900,11 @@ inline void vm::o_callfv() {
var tmp = local[-1]; var tmp = local[-1];
local[-1] = ctx.funcr; local[-1] = ctx.funcr;
ctx.funcr = tmp; ctx.funcr = tmp;
(++ctx.func_top)[0] = tmp; (++ctx.func_top)[0] = {
tmp,
bytecode[ctx.pc].fidx,
bytecode[ctx.pc].line
};
// top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr) // top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
if (ctx.top-argc+func.local_size+3>=ctx.canary) { if (ctx.top-argc+func.local_size+3>=ctx.canary) {
@@ -972,7 +974,11 @@ inline void vm::o_callfh() {
var tmp = ctx.top[-1]; var tmp = ctx.top[-1];
ctx.top[-1] = ctx.funcr; ctx.top[-1] = ctx.funcr;
ctx.funcr = tmp; ctx.funcr = tmp;
(++ctx.func_top)[0] = tmp; (++ctx.func_top)[0] = {
tmp,
bytecode[ctx.pc].fidx,
bytecode[ctx.pc].line
};
// top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr) // top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
if (ctx.top+func.local_size+2>= ctx.canary) { if (ctx.top+func.local_size+2>= ctx.canary) {
@@ -1015,6 +1021,9 @@ inline void vm::o_callb() {
// this code is written for coroutine // this code is written for coroutine
(++ctx.top)[0] = nil; (++ctx.top)[0] = nil;
// set file list into ctx
ctx.files = files;
// if running a native function about coroutine // if running a native function about coroutine
// (top) will be set to another context.top, instead of main_context.top // (top) will be set to another context.top, instead of main_context.top
auto function_pointer = native_function[imm[ctx.pc]].func; auto function_pointer = native_function[imm[ctx.pc]].func;

View File

@@ -538,7 +538,14 @@ var builtin_caller(context* ctx, gc* ngc) {
if (ctx->func_top - level_num - 1 < ctx->func_stack) { if (ctx->func_top - level_num - 1 < ctx->func_stack) {
return nil; return nil;
} }
return ctx->func_top[-level_num - 1]; const auto& cs = ctx->func_top[-level_num - 1];
var res = ngc->temp = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(ngc->alloc(vm_type::vm_hash));
res.vec().elems.push_back(cs.caller);
res.vec().elems.push_back(ngc->newstr(ctx->files[cs.file_index]));
res.vec().elems.push_back(var::num(cs.line));
ngc->temp = nil;
return res;
} }
var builtin_arch(context* ctx, gc* ngc) { var builtin_arch(context* ctx, gc* ngc) {

24
test/caller.nas Normal file
View File

@@ -0,0 +1,24 @@
var a = func(x, y, z) {
for (var i = 0; i < 20; i += 1) {
var cl = caller(i);
if (cl == nil) {
return;
}
print("[", i, "]\t", cl[1], "\t -> called from ", cl[2], ":", cl[3], "\n");
}
}
var b = func(x, y) {
a(1, 2, 3);
}
var c = func(x) b(1, 2);
var d = func c(1);
var e = func d();
var f = func e();
var g = func f();
var h = func g();
var i = func h();
var j = func i();
j();

View File

@@ -109,7 +109,7 @@ for (var t = 0; t < 10; t += 1) {
counter += 1; counter += 1;
for (var i = 0; i < t + 1; i += 1) for (var i = 0; i < t + 1; i += 1)
coroutine.resume(co); coroutine.resume(co);
if (counter - int(counter / 1000) * 1000 == 0) { if (counter - int(counter / 2500) * 2500 == 0) {
var rate = counter / 2e5; var rate = counter / 2e5;
print(" ", bar.bar(rate), " ", print(" ", bar.bar(rate), " ",
padding.leftpad(str(int(rate*100)),3), "% | ", padding.leftpad(str(int(rate*100)),3), "% | ",
@@ -120,7 +120,7 @@ for (var t = 0; t < 10; t += 1) {
} }
tm.stamp(); tm.stamp();
for (var i = 0; i < 1e5; i += 1) for (var i = 0; i < 2e5; i += 1)
consumer(); consumer();
println(" ", bar.bar(1), " 100% | ", println(" ", bar.bar(1), " 100% | ",
str(int(1e3 * counter / tm.elapsedMSec())), str(int(1e3 * counter / tm.elapsedMSec())),