You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

133 lines
3.1 KiB

/*
* dpas-function.c - Special handling for Dynamic Pascal functions.
*
* Copyright (C) 2004 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dpas-internal.h"
static jit_context_t current_context;
static jit_function_t *function_stack = 0;
static int function_stack_size = 0;
static jit_function_t *main_list = 0;
static int main_list_size = 0;
jit_context_t dpas_current_context(void)
{
if(!current_context)
{
current_context = jit_context_create();
if(!current_context)
{
dpas_out_of_memory();
}
}
return current_context;
}
jit_function_t dpas_current_function(void)
{
if(function_stack_size > 0)
{
return function_stack[function_stack_size - 1];
}
else
{
/* We are probably compiling the "main" method for this module */
jit_type_t signature = jit_type_create_signature
(jit_abi_cdecl, jit_type_void, 0, 0, 1);
if(!signature)
{
dpas_out_of_memory();
}
return dpas_new_function(signature);
}
}
jit_function_t dpas_new_function(jit_type_t signature)
{
jit_function_t func;
func = jit_function_create(dpas_current_context(), signature);
if(!func)
{
dpas_out_of_memory();
}
function_stack = (jit_function_t *)jit_realloc
(function_stack, sizeof(jit_function_t) * (function_stack_size + 1));
if(!function_stack)
{
dpas_out_of_memory();
}
function_stack[function_stack_size++] = func;
return func;
}
void dpas_pop_function(void)
{
if(function_stack_size > 0)
{
--function_stack_size;
}
}
int dpas_function_is_nested(void)
{
return (function_stack_size > 1);
}
dpas_semvalue dpas_lvalue_to_rvalue(dpas_semvalue value)
{
if(dpas_sem_is_lvalue_ea(value))
{
jit_type_t type = dpas_sem_get_type(value);
jit_value_t rvalue = dpas_sem_get_value(value);
rvalue = jit_insn_load_relative
(dpas_current_function(), rvalue, 0, type);
if(!rvalue)
{
dpas_out_of_memory();
}
dpas_sem_set_rvalue(value, type, rvalue);
}
return value;
}
void dpas_add_main_function(jit_function_t func)
{
main_list = (jit_function_t *)jit_realloc
(main_list, sizeof(jit_function_t) * (main_list_size + 1));
if(!main_list)
{
dpas_out_of_memory();
}
main_list[main_list_size++] = func;
}
int dpas_run_main_functions(void)
{
int index;
for(index = 0; index < main_list_size; ++index)
{
if(!jit_function_apply(main_list[index], 0, 0))
{
fprintf(stderr, "Exception 0x%lx thrown past top level\n",
(long)(jit_nint)(jit_exception_get_last()));
return 0;
}
}
return 1;
}