feat: optimize runtime (2x+ faster)
This commit is contained in:
+35
-18
@@ -855,14 +855,10 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
|
||||
case FZL_NODETYPE_IDENTIFIER:
|
||||
{
|
||||
size_t n = add_const(
|
||||
walker, (fzl_const_t){.type = FZL_CONSTTYPE_STRING,
|
||||
.as.string.chars = node->token->value,
|
||||
.as.string.length = node->token->value_sz});
|
||||
|
||||
fzl_sym_t sym;
|
||||
bool exists = false;
|
||||
for (ssize_t i = walker->sym_top - 1; i >= 0; i--)
|
||||
ssize_t i = walker->sym_top - 1;
|
||||
for (; i >= 0; i--)
|
||||
if ((exists =
|
||||
fzl_symt_get(walker->syms[i], node->token->value, &sym)))
|
||||
break;
|
||||
@@ -876,9 +872,17 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
push_op(walker, FZL_OPCODE_LOADCONST);
|
||||
push_word(walker, n);
|
||||
push_op(walker, FZL_OPCODE_LOOKUP_ENV);
|
||||
if (!sym.slot_set)
|
||||
{
|
||||
snprintf(wlast_err, sizeof(wlast_err),
|
||||
"internal error: local '%s' has no slot", sym.name);
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
size_t depth = walker->sym_top - 1 - i;
|
||||
push_op(walker, FZL_OPCODE_LOAD_LOCAL);
|
||||
push_word(walker, depth);
|
||||
push_word(walker, sym.slot);
|
||||
|
||||
current_res = (fzl_walk_res_t){
|
||||
.type = sym.type, .error = false, .classname = sym.classname};
|
||||
@@ -1239,6 +1243,15 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
if (fzl_symt_setslot(walker->syms[walker->sym_top - 1],
|
||||
node->var.identifier->token->value) < 0)
|
||||
{
|
||||
snprintf(wlast_err, sizeof(wlast_err),
|
||||
"failed to assign a local slot to '%s'",
|
||||
(char *)node->var.identifier->token->value);
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
fzl_token_t *id_tok = node->var.identifier->token;
|
||||
size_t const_n = add_const(
|
||||
walker, (fzl_const_t){.type = FZL_CONSTTYPE_STRING,
|
||||
@@ -1283,7 +1296,8 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
{
|
||||
fzl_sym_t sym;
|
||||
bool found = false;
|
||||
for (ssize_t i = walker->sym_top - 1; i >= 0; i--)
|
||||
ssize_t i = walker->sym_top - 1;
|
||||
for (; i >= 0; i--)
|
||||
if ((found =
|
||||
fzl_symt_get(walker->syms[i],
|
||||
node->binary_op.left->token->value, &sym)))
|
||||
@@ -1308,14 +1322,17 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
size_t const_n = add_const(
|
||||
walker, (fzl_const_t){.type = FZL_CONSTTYPE_STRING,
|
||||
.as.string.chars = sym.name,
|
||||
.as.string.length =
|
||||
node->binary_op.left->token->value_sz});
|
||||
push_op(walker, FZL_OPCODE_LOADCONST);
|
||||
push_word(walker, const_n);
|
||||
push_op(walker, FZL_OPCODE_WRITE);
|
||||
if (!sym.slot_set)
|
||||
{
|
||||
snprintf(wlast_err, sizeof(wlast_err),
|
||||
"internal error: local '%s' has no slot", sym.name);
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
size_t depth = walker->sym_top - 1 - i;
|
||||
push_op(walker, FZL_OPCODE_STORE_LOCAL);
|
||||
push_word(walker, depth);
|
||||
push_word(walker, sym.slot);
|
||||
}
|
||||
else if (node->binary_op.left->type == FZL_NODETYPE_FIELD)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ fzl_symtable_t *fzl_mksymt()
|
||||
if (!tbl)
|
||||
return NULL;
|
||||
|
||||
tbl->free_slot = 0;
|
||||
tbl->remainder = 2;
|
||||
tbl->size = 0;
|
||||
tbl->symbols = malloc(tbl->remainder * sizeof(fzl_sym_t));
|
||||
@@ -38,8 +39,13 @@ fzl_symtable_res_t fzl_symt_put(fzl_symtable_t *symt, fzl_node_t *node,
|
||||
symt->symbols = realloc(symt->symbols, symt->remainder * sizeof(fzl_sym_t));
|
||||
}
|
||||
|
||||
symt->symbols[symt->size++] = (fzl_sym_t){
|
||||
.name = name, .node = node, .type = type, .ip = ip, .classname = NULL};
|
||||
symt->symbols[symt->size++] = (fzl_sym_t){.name = name,
|
||||
.node = node,
|
||||
.type = type,
|
||||
.ip = ip,
|
||||
.classname = NULL,
|
||||
.slot_set = false,
|
||||
.slot = 0};
|
||||
return FZL_SYMTABLE_RESULT_OK;
|
||||
}
|
||||
|
||||
@@ -64,6 +70,28 @@ fzl_symtable_res_t fzl_symt_setobjclass(fzl_symtable_t *symt, char *name,
|
||||
return FZL_SYMTABLE_RESULT_ERR;
|
||||
}
|
||||
|
||||
int fzl_symt_setslot(fzl_symtable_t *symt, char *name)
|
||||
{
|
||||
if (!symt)
|
||||
return -1;
|
||||
|
||||
for (size_t i = 0; i < symt->size; i++)
|
||||
{
|
||||
if (strcmp(symt->symbols[i].name, name) == 0)
|
||||
{
|
||||
if (symt->symbols[i].slot_set)
|
||||
return symt->symbols[i].slot;
|
||||
|
||||
symt->symbols[i].slot = symt->free_slot++;
|
||||
symt->symbols[i].slot_set = true;
|
||||
|
||||
return symt->symbols[i].slot;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool fzl_symt_get(fzl_symtable_t *symt, char *name, fzl_sym_t *res)
|
||||
{
|
||||
if (!symt)
|
||||
|
||||
Reference in New Issue
Block a user