runtime: fix memory leaks
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#define BSHELL_RUNTIME_RUNTIME_H_
|
#define BSHELL_RUNTIME_RUNTIME_H_
|
||||||
|
|
||||||
#include <bshell/command/command.h>
|
#include <bshell/command/command.h>
|
||||||
|
#include <bshell/command/function.h>
|
||||||
#include <bshell/runtime/script-block.h>
|
#include <bshell/runtime/script-block.h>
|
||||||
#include <bshell/runtime/var.h>
|
#include <bshell/runtime/var.h>
|
||||||
#include <fx/collections/hashtable.h>
|
#include <fx/collections/hashtable.h>
|
||||||
@@ -32,6 +33,9 @@ extern bshell_variable *bshell_runtime_find_var(
|
|||||||
extern bshell_variable *bshell_runtime_define_var(
|
extern bshell_variable *bshell_runtime_define_var(
|
||||||
struct bshell_runtime *rt,
|
struct bshell_runtime *rt,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
extern enum bshell_status bshell_runtime_define_function(
|
||||||
|
struct bshell_runtime *rt,
|
||||||
|
bshell_function *func);
|
||||||
|
|
||||||
extern bshell_command *bshell_runtime_find_command(
|
extern bshell_command *bshell_runtime_find_command(
|
||||||
struct bshell_runtime *rt,
|
struct bshell_runtime *rt,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ extern bshell_variable *bshell_variable_create(const char *name);
|
|||||||
|
|
||||||
extern const char *bshell_variable_get_name(const bshell_variable *var);
|
extern const char *bshell_variable_get_name(const bshell_variable *var);
|
||||||
extern const fx_value *bshell_variable_get_value(const bshell_variable *var);
|
extern const fx_value *bshell_variable_get_value(const bshell_variable *var);
|
||||||
extern void bshell_variable_set_value(bshell_variable *var, fx_value *value);
|
extern void bshell_variable_set_value(bshell_variable *var, fx_value value);
|
||||||
|
|
||||||
FX_DECLS_END;
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ static void cmdcall_fini(fx_object *obj, void *priv)
|
|||||||
{
|
{
|
||||||
struct bshell_cmdcall_p *cmdcall = priv;
|
struct bshell_cmdcall_p *cmdcall = priv;
|
||||||
|
|
||||||
|
if (cmdcall->cmd_target) {
|
||||||
|
bshell_command_end_processing(cmdcall->cmd_target);
|
||||||
|
bshell_command_unref(cmdcall->cmd_target);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmdcall->cmd_native_path) {
|
if (cmdcall->cmd_native_path) {
|
||||||
free(cmdcall->cmd_native_path);
|
free(cmdcall->cmd_native_path);
|
||||||
}
|
}
|
||||||
@@ -44,11 +49,6 @@ static void cmdcall_fini(fx_object *obj, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fx_vector_destroy(cmdcall->cmd_args, NULL);
|
fx_vector_destroy(cmdcall->cmd_args, NULL);
|
||||||
|
|
||||||
if (cmdcall->cmd_target) {
|
|
||||||
bshell_command_end_processing(cmdcall->cmd_target);
|
|
||||||
bshell_command_unref(cmdcall->cmd_target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum bshell_status cmdcall_push_arg(
|
static enum bshell_status cmdcall_push_arg(
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ static enum bshell_status eval_instruction(
|
|||||||
pool_value = bshell_scriptblock_get_pool_value(
|
pool_value = bshell_scriptblock_get_pool_value(
|
||||||
scope->s_block,
|
scope->s_block,
|
||||||
arg,
|
arg,
|
||||||
FX_TYPE_CSTR);
|
FX_TYPE_STRING);
|
||||||
if (!pool_value) {
|
if (!pool_value) {
|
||||||
fprintf(stderr, "RUNTIME: invalid stlocal operand\n");
|
fprintf(stderr, "RUNTIME: invalid stlocal operand\n");
|
||||||
return BSHELL_ERR_BAD_SYNTAX;
|
return BSHELL_ERR_BAD_SYNTAX;
|
||||||
@@ -253,7 +253,7 @@ static enum bshell_status eval_instruction(
|
|||||||
var = bshell_runtime_define_var(rt, s);
|
var = bshell_runtime_define_var(rt, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bshell_variable_set_value(var, &x);
|
bshell_variable_set_value(var, x);
|
||||||
bshell_runtime_scope_push_value(scope, &x);
|
bshell_runtime_scope_push_value(scope, &x);
|
||||||
fx_value_unset(&x);
|
fx_value_unset(&x);
|
||||||
break;
|
break;
|
||||||
@@ -314,7 +314,8 @@ static enum bshell_status eval_instruction(
|
|||||||
bshell_cmdcall *result = bshell_cmdcall_create();
|
bshell_cmdcall *result = bshell_cmdcall_create();
|
||||||
|
|
||||||
while (arg > 0) {
|
while (arg > 0) {
|
||||||
fx_value cmd_arg = bshell_runtime_scope_pop_value(scope);
|
fx_value cmd_arg
|
||||||
|
= bshell_runtime_scope_pop_value(scope);
|
||||||
bshell_cmdcall_push_arg(result, cmd_arg);
|
bshell_cmdcall_push_arg(result, cmd_arg);
|
||||||
fx_value_unset(&cmd_arg);
|
fx_value_unset(&cmd_arg);
|
||||||
arg--;
|
arg--;
|
||||||
@@ -322,6 +323,7 @@ static enum bshell_status eval_instruction(
|
|||||||
|
|
||||||
bstatus = bshell_cmdcall_resolve(result, rt);
|
bstatus = bshell_cmdcall_resolve(result, rt);
|
||||||
if (bstatus != BSHELL_SUCCESS) {
|
if (bstatus != BSHELL_SUCCESS) {
|
||||||
|
bshell_cmdcall_unref(result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,7 +424,9 @@ fx_value bshell_runtime_eval_global(
|
|||||||
{
|
{
|
||||||
enum bshell_status status = BSHELL_SUCCESS;
|
enum bshell_status status = BSHELL_SUCCESS;
|
||||||
bshell_runtime_scope_set_block(rt->rt_global, block);
|
bshell_runtime_scope_set_block(rt->rt_global, block);
|
||||||
return runtime_eval(rt);
|
fx_value result = runtime_eval(rt);
|
||||||
|
bshell_runtime_scope_set_block(rt->rt_global, NULL);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fx_value bshell_runtime_eval_script(
|
fx_value bshell_runtime_eval_script(
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ static void pipeline_fini(fx_object *obj, void *priv)
|
|||||||
for (size_t i = 0; i < pipeline->p_cmds.count; i++) {
|
for (size_t i = 0; i < pipeline->p_cmds.count; i++) {
|
||||||
bshell_cmdcall_unref(pipeline->p_cmds.items[i]);
|
bshell_cmdcall_unref(pipeline->p_cmds.items[i]);
|
||||||
}
|
}
|
||||||
|
fx_vector_destroy(pipeline->p_cmds, NULL);
|
||||||
|
|
||||||
if (pipeline->p_in) {
|
if (pipeline->p_in) {
|
||||||
fx_array_unref(pipeline->p_in);
|
fx_array_unref(pipeline->p_in);
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ struct bshell_runtime *bshell_runtime_create(void)
|
|||||||
|
|
||||||
void bshell_runtime_destroy(struct bshell_runtime *rt)
|
void bshell_runtime_destroy(struct bshell_runtime *rt)
|
||||||
{
|
{
|
||||||
|
while (!fx_queue_empty(&rt->rt_scope)) {
|
||||||
|
runtime_pop_scope(rt);
|
||||||
|
}
|
||||||
|
|
||||||
fx_hashtable_unref(rt->rt_aliases);
|
fx_hashtable_unref(rt->rt_aliases);
|
||||||
free(rt);
|
free(rt);
|
||||||
}
|
}
|
||||||
@@ -63,6 +67,31 @@ bshell_variable *bshell_runtime_define_var(
|
|||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum bshell_status bshell_runtime_define_function(
|
||||||
|
struct bshell_runtime *rt,
|
||||||
|
bshell_function *func)
|
||||||
|
{
|
||||||
|
struct bshell_runtime_scope *scope = runtime_get_scope(rt);
|
||||||
|
if (!scope) {
|
||||||
|
return BSHELL_ERR_BAD_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_string *name
|
||||||
|
= fx_string_create_from_cstr(bshell_function_get_name(func));
|
||||||
|
if (!name) {
|
||||||
|
return BSHELL_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_string_transform_lowercase(name);
|
||||||
|
fx_hashtable_put(
|
||||||
|
scope->s_functions,
|
||||||
|
&FX_VALUE_OBJECT(name),
|
||||||
|
&FX_VALUE_OBJECT(func));
|
||||||
|
fx_string_unref(name);
|
||||||
|
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
bshell_command *bshell_runtime_find_command(
|
bshell_command *bshell_runtime_find_command(
|
||||||
struct bshell_runtime *rt,
|
struct bshell_runtime *rt,
|
||||||
const char *callable_name)
|
const char *callable_name)
|
||||||
|
|||||||
@@ -37,7 +37,14 @@ void runtime_pop_scope(struct bshell_runtime *rt)
|
|||||||
|
|
||||||
struct bshell_runtime_scope *scope
|
struct bshell_runtime_scope *scope
|
||||||
= fx_unbox(struct bshell_runtime_scope, entry, s_entry);
|
= fx_unbox(struct bshell_runtime_scope, entry, s_entry);
|
||||||
/* TODO */
|
|
||||||
|
if (scope->s_block) {
|
||||||
|
bshell_scriptblock_unref(scope->s_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_value_unset_array(scope->s_stack.items, scope->s_stack.count);
|
||||||
|
var_map_cleanup(&scope->s_vars);
|
||||||
|
fx_vector_destroy(scope->s_stack, NULL);
|
||||||
fx_hashtable_unref(scope->s_functions);
|
fx_hashtable_unref(scope->s_functions);
|
||||||
free(scope);
|
free(scope);
|
||||||
}
|
}
|
||||||
@@ -79,7 +86,11 @@ void bshell_runtime_scope_set_block(
|
|||||||
struct bshell_runtime_scope *scope,
|
struct bshell_runtime_scope *scope,
|
||||||
bshell_scriptblock *block)
|
bshell_scriptblock *block)
|
||||||
{
|
{
|
||||||
scope->s_block = block;
|
if (scope->s_block) {
|
||||||
|
bshell_scriptblock_unref(scope->s_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope->s_block = bshell_scriptblock_ref(block);
|
||||||
scope->s_ip = 0;
|
scope->s_ip = 0;
|
||||||
bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr);
|
bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr);
|
||||||
bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool);
|
bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool);
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
#include "var-map.h"
|
#include "var-map.h"
|
||||||
|
|
||||||
|
static void var_entry_cleanup(fx_namemap_entry *entry)
|
||||||
|
{
|
||||||
|
struct var_map_entry *map_entry
|
||||||
|
= fx_unbox(struct var_map_entry, entry, e_entry);
|
||||||
|
bshell_variable_unref(map_entry->e_var);
|
||||||
|
free(map_entry);
|
||||||
|
}
|
||||||
|
|
||||||
void var_map_cleanup(struct var_map *map)
|
void var_map_cleanup(struct var_map *map)
|
||||||
{
|
{
|
||||||
|
fx_namemap_cleanup(&map->m_vars, var_entry_cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum bshell_status var_map_put(struct var_map *map, bshell_variable *var)
|
enum bshell_status var_map_put(struct var_map *map, bshell_variable *var)
|
||||||
@@ -27,9 +36,7 @@ bshell_variable *var_map_get(struct var_map *map, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct var_map_entry *entry = fx_unbox(
|
struct var_map_entry *entry
|
||||||
struct var_map_entry,
|
= fx_unbox(struct var_map_entry, e, e_entry);
|
||||||
e,
|
|
||||||
e_entry);
|
|
||||||
return entry->e_var;
|
return entry->e_var;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ static const fx_value *variable_get_value(const struct bshell_variable_p *var)
|
|||||||
return &var->var_value;
|
return &var->var_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void variable_set_value(struct bshell_variable_p *var, fx_value *value)
|
static void variable_set_value(struct bshell_variable_p *var, fx_value value)
|
||||||
{
|
{
|
||||||
fx_value_unset(&var->var_value);
|
fx_value_unset(&var->var_value);
|
||||||
fx_value_copy(&var->var_value, value);
|
var->var_value = fx_value_copy_return(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bshell_variable *bshell_variable_create(const char *name)
|
bshell_variable *bshell_variable_create(const char *name)
|
||||||
@@ -70,7 +70,7 @@ const fx_value *bshell_variable_get_value(const bshell_variable *var)
|
|||||||
var);
|
var);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bshell_variable_set_value(bshell_variable *var, fx_value *value)
|
void bshell_variable_set_value(bshell_variable *var, fx_value value)
|
||||||
{
|
{
|
||||||
FX_CLASS_DISPATCH_STATIC_V(
|
FX_CLASS_DISPATCH_STATIC_V(
|
||||||
BSHELL_TYPE_VARIABLE,
|
BSHELL_TYPE_VARIABLE,
|
||||||
|
|||||||
Reference in New Issue
Block a user