mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 13:02:11 +00:00
Optimize member function calls to use less string manipulation.
[SVN r83937]
This commit is contained in:
@@ -54,35 +54,28 @@ void unknown_rule( FRAME *, char const * key, module_t *, OBJECT * rule_name );
|
||||
* evaluate_rule() - execute a rule invocation
|
||||
*/
|
||||
|
||||
LIST * evaluate_rule( OBJECT * rulename, FRAME * frame )
|
||||
LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * frame )
|
||||
{
|
||||
LIST * result = L0;
|
||||
RULE * rule;
|
||||
profile_frame prof[ 1 ];
|
||||
module_t * prev_module = frame->module;
|
||||
|
||||
rule = bindrule( rulename, frame->module );
|
||||
|
||||
if ( DEBUG_COMPILE )
|
||||
{
|
||||
/* Try hard to indicate in which module the rule is going to execute. */
|
||||
if ( rule->module != frame->module && rule->procedure && !object_equal(
|
||||
rulename, function_rulename( rule->procedure ) ) )
|
||||
char buf[ 256 ] = "";
|
||||
if ( rule->module->name )
|
||||
{
|
||||
char buf[ 256 ] = "";
|
||||
if ( rule->module->name )
|
||||
strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
|
||||
1 );
|
||||
strncat( buf, ".", sizeof( buf ) - 1 );
|
||||
if ( strncmp( buf, object_str( rule->name ), strlen( buf ) ) == 0 )
|
||||
{
|
||||
strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
|
||||
1 );
|
||||
strncat( buf, ".", sizeof( buf ) - 1 );
|
||||
buf[ 0 ] = 0;
|
||||
}
|
||||
strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
|
||||
debug_compile( 1, buf, frame );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_compile( 1, object_str( rulename ), frame );
|
||||
}
|
||||
strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
|
||||
debug_compile( 1, buf, frame );
|
||||
|
||||
lol_print( frame->args );
|
||||
printf( "\n" );
|
||||
@@ -238,7 +231,7 @@ LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... )
|
||||
}
|
||||
va_end( va );
|
||||
|
||||
result = evaluate_rule( rulename, inner );
|
||||
result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
|
||||
|
||||
frame_free( inner );
|
||||
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
#include "frames.h"
|
||||
#include "lists.h"
|
||||
#include "object.h"
|
||||
#include "rules.h"
|
||||
|
||||
void compile_builtins();
|
||||
|
||||
LIST * evaluate_rule( OBJECT * rulename, FRAME * );
|
||||
LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * );
|
||||
LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... );
|
||||
|
||||
/* Flags for compile_set(), etc */
|
||||
|
||||
@@ -96,6 +96,7 @@ void backtrace_line( FRAME * );
|
||||
#define INSTR_GET_ON 65
|
||||
|
||||
#define INSTR_CALL_RULE 39
|
||||
#define INSTR_CALL_MEMBER_RULE 66
|
||||
|
||||
#define INSTR_APPLY_MODIFIERS 40
|
||||
#define INSTR_APPLY_INDEX 41
|
||||
@@ -472,12 +473,111 @@ static LIST * function_call_rule( JAM_FUNCTION * function, FRAME * frame,
|
||||
}
|
||||
}
|
||||
|
||||
result = evaluate_rule( rulename, inner );
|
||||
result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
|
||||
frame_free( inner );
|
||||
object_free( rulename );
|
||||
return result;
|
||||
}
|
||||
|
||||
static LIST * function_call_member_rule( JAM_FUNCTION * function, FRAME * frame, STACK * s, int n_args, OBJECT * rulename, OBJECT * file, int line )
|
||||
{
|
||||
FRAME inner[ 1 ];
|
||||
int i;
|
||||
LIST * first = stack_pop( s );
|
||||
LIST * result = L0;
|
||||
LIST * trailing;
|
||||
RULE * rule;
|
||||
module_t * module;
|
||||
OBJECT * real_rulename = 0;
|
||||
|
||||
frame->file = file;
|
||||
frame->line = line;
|
||||
|
||||
if ( list_empty( first ) )
|
||||
{
|
||||
backtrace_line( frame );
|
||||
printf( "warning: object is empty\n" );
|
||||
backtrace( frame );
|
||||
|
||||
list_free( first );
|
||||
|
||||
for( i = 0; i < n_args; ++i )
|
||||
{
|
||||
list_free( stack_pop( s ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME: handle generic case */
|
||||
assert( list_length( first ) == 1 );
|
||||
|
||||
module = bindmodule( list_front( first ) );
|
||||
if ( module->class_module )
|
||||
{
|
||||
rule = bindrule( rulename, module );
|
||||
real_rulename = object_copy( function_rulename( rule->procedure ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
string buf[ 1 ];
|
||||
string_new( buf );
|
||||
string_append( buf, object_str( list_front( first ) ) );
|
||||
string_push_back( buf, '.' );
|
||||
string_append( buf, object_str( rulename ) );
|
||||
real_rulename = object_new( buf->value );
|
||||
string_free( buf );
|
||||
rule = bindrule( real_rulename, frame->module );
|
||||
}
|
||||
|
||||
frame_init( inner );
|
||||
|
||||
inner->prev = frame;
|
||||
inner->prev_user = frame->module->user_module ? frame : frame->prev_user;
|
||||
inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below. */
|
||||
|
||||
for( i = 0; i < n_args; ++i )
|
||||
{
|
||||
lol_add( inner->args, stack_at( s, n_args - i - 1 ) );
|
||||
}
|
||||
|
||||
for( i = 0; i < n_args; ++i )
|
||||
{
|
||||
stack_pop( s );
|
||||
}
|
||||
|
||||
if ( list_length( first ) > 1 )
|
||||
{
|
||||
string buf[ 1 ];
|
||||
LIST * trailing = L0;
|
||||
LISTITER iter = list_begin( first ), end = list_end( first );
|
||||
iter = list_next( iter );
|
||||
string_new( buf );
|
||||
for ( ; iter != end; iter = list_next( iter ) )
|
||||
{
|
||||
string_append( buf, object_str( list_item( iter ) ) );
|
||||
string_push_back( buf, '.' );
|
||||
string_append( buf, object_str( rulename ) );
|
||||
trailing = list_push_back( trailing, object_new( buf->value ) );
|
||||
string_truncate( buf, 0 );
|
||||
}
|
||||
string_free( buf );
|
||||
if ( inner->args->count == 0 )
|
||||
lol_add( inner->args, trailing );
|
||||
else
|
||||
{
|
||||
LIST * * const l = &inner->args->list[ 0 ];
|
||||
*l = list_append( trailing, *l );
|
||||
}
|
||||
}
|
||||
|
||||
result = evaluate_rule( rule, real_rulename, inner );
|
||||
frame_free( inner );
|
||||
object_free( rulename );
|
||||
object_free( real_rulename );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Variable expansion */
|
||||
|
||||
@@ -2557,11 +2657,29 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location )
|
||||
current_file = object_str( parse->file );
|
||||
current_line = parse->line;
|
||||
group = parse_expansion( &s );
|
||||
var_parse_group_compile( group, c );
|
||||
var_parse_group_free( group );
|
||||
compile_emit( c, INSTR_CALL_RULE, n );
|
||||
compile_emit( c, compile_emit_constant( c, parse->string ), parse->line
|
||||
);
|
||||
|
||||
if ( group->elems->size == 2 &&
|
||||
dynamic_array_at( VAR_PARSE *, group->elems, 0 )->type == VAR_PARSE_TYPE_VAR &&
|
||||
dynamic_array_at( VAR_PARSE *, group->elems, 1 )->type == VAR_PARSE_TYPE_STRING &&
|
||||
( object_str( ( (VAR_PARSE_STRING *)dynamic_array_at( VAR_PARSE *, group->elems, 1 ) )->s )[ 0 ] == '.' ) )
|
||||
{
|
||||
VAR_PARSE_STRING * access = (VAR_PARSE_STRING *)dynamic_array_at( VAR_PARSE *, group->elems, 1 );
|
||||
OBJECT * member = object_new( object_str( access->s ) + 1 );
|
||||
/* Emit the object */
|
||||
var_parse_var_compile( (VAR_PARSE_VAR *)dynamic_array_at( VAR_PARSE *, group->elems, 0 ), c );
|
||||
var_parse_group_free( group );
|
||||
compile_emit( c, INSTR_CALL_MEMBER_RULE, n );
|
||||
compile_emit( c, compile_emit_constant( c, member ), parse->line );
|
||||
object_free( member );
|
||||
}
|
||||
else
|
||||
{
|
||||
var_parse_group_compile( group, c );
|
||||
var_parse_group_free( group );
|
||||
compile_emit( c, INSTR_CALL_RULE, n );
|
||||
compile_emit( c, compile_emit_constant( c, parse->string ), parse->line );
|
||||
}
|
||||
|
||||
adjust_result( c, RESULT_STACK, result_location );
|
||||
}
|
||||
else if ( parse->type == PARSE_RULES )
|
||||
@@ -2840,7 +2958,7 @@ static void type_check_range( OBJECT * type_name, LISTITER iter, LISTITER end,
|
||||
|
||||
/* Prepare the argument list */
|
||||
lol_add( frame->args, list_new( object_copy( list_item( iter ) ) ) );
|
||||
error = evaluate_rule( type_name, frame );
|
||||
error = evaluate_rule( bindrule( type_name, frame->module ), type_name, frame );
|
||||
|
||||
if ( !list_empty( error ) )
|
||||
argument_error( object_str( list_front( error ) ), called, caller,
|
||||
@@ -3396,6 +3514,7 @@ FUNCTION * function_bind_variables( FUNCTION * f, module_t * module,
|
||||
case INSTR_APPEND: op_code = INSTR_APPEND_FIXED; break;
|
||||
case INSTR_DEFAULT: op_code = INSTR_DEFAULT_FIXED; break;
|
||||
case INSTR_RETURN: return (FUNCTION *)new_func;
|
||||
case INSTR_CALL_MEMBER_RULE:
|
||||
case INSTR_CALL_RULE: ++i; continue;
|
||||
case INSTR_PUSH_MODULE:
|
||||
{
|
||||
@@ -4114,6 +4233,15 @@ LIST * function_run( FUNCTION * function_, FRAME * frame, STACK * s )
|
||||
break;
|
||||
}
|
||||
|
||||
case INSTR_CALL_MEMBER_RULE:
|
||||
{
|
||||
OBJECT * rule_name = function_get_constant( function, code[1].op_code );
|
||||
LIST * result = function_call_member_rule( function, frame, s, code->arg, rule_name, function->file, code[1].arg );
|
||||
stack_push( s, result );
|
||||
++code;
|
||||
break;
|
||||
}
|
||||
|
||||
case INSTR_RULE:
|
||||
function_set_rule( function, frame, s, code->arg );
|
||||
break;
|
||||
|
||||
@@ -96,9 +96,10 @@ void headers( TARGET * t )
|
||||
|
||||
if ( lol_get( frame->args, 1 ) )
|
||||
{
|
||||
OBJECT * rulename = list_front( hdrrule );
|
||||
/* The third argument to HDRRULE is the bound name of $(<). */
|
||||
lol_add( frame->args, list_new( object_copy( t->boundname ) ) );
|
||||
list_free( evaluate_rule( list_front( hdrrule ), frame ) );
|
||||
list_free( evaluate_rule( bindrule( rulename, frame->module ), rulename, frame ) );
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
@@ -739,6 +739,7 @@ static void call_timing_rule( TARGET * target, timing_info const * const time )
|
||||
|
||||
/* Prepare the argument list. */
|
||||
FRAME frame[ 1 ];
|
||||
OBJECT * rulename = list_front( timing_rule );
|
||||
frame_init( frame );
|
||||
|
||||
/* args * :: $(__TIMING_RULE__[2-]) */
|
||||
@@ -756,7 +757,7 @@ static void call_timing_rule( TARGET * target, timing_info const * const time )
|
||||
outf_double( time->system ) ) );
|
||||
|
||||
/* Call the rule. */
|
||||
evaluate_rule( list_front( timing_rule ), frame );
|
||||
evaluate_rule( bindrule( rulename , root_module() ), rulename, frame );
|
||||
|
||||
/* Clean up. */
|
||||
frame_free( frame );
|
||||
@@ -795,6 +796,7 @@ static void call_action_rule
|
||||
|
||||
/* Prepare the argument list. */
|
||||
FRAME frame[ 1 ];
|
||||
OBJECT * rulename = list_front( action_rule );
|
||||
frame_init( frame );
|
||||
|
||||
/* args * :: $(__ACTION_RULE__[2-]) */
|
||||
@@ -822,7 +824,7 @@ static void call_action_rule
|
||||
lol_add( frame->args, L0 );
|
||||
|
||||
/* Call the rule. */
|
||||
evaluate_rule( list_front( action_rule ), frame );
|
||||
evaluate_rule( bindrule( rulename, root_module() ), rulename, frame );
|
||||
|
||||
/* Clean up. */
|
||||
frame_free( frame );
|
||||
|
||||
@@ -62,6 +62,7 @@ LIST * sequence_transform( FRAME * frame, int flags )
|
||||
OBJECT * function_name = list_front( function );
|
||||
LISTITER args_begin = list_next( list_begin( function ) ), args_end = list_end( function );
|
||||
LISTITER iter = list_begin( sequence ), end = list_end( sequence );
|
||||
RULE * rule = bindrule( function_name, frame->prev->module );
|
||||
|
||||
for ( ; iter != end; iter = list_next( iter ) )
|
||||
{
|
||||
@@ -73,7 +74,7 @@ LIST * sequence_transform( FRAME * frame, int flags )
|
||||
inner->module = frame->prev->module;
|
||||
|
||||
lol_add( inner->args, list_push_back( list_copy_range( function, args_begin, args_end ), object_copy( list_item( iter ) ) ) );
|
||||
result = list_append( result, evaluate_rule( function_name, inner ) );
|
||||
result = list_append( result, evaluate_rule( rule, function_name, inner ) );
|
||||
|
||||
frame_free( inner );
|
||||
}
|
||||
|
||||
@@ -54,7 +54,10 @@ void call_bind_rule( OBJECT * target_, OBJECT * boundname_ )
|
||||
|
||||
lol_add( frame->args, list_new( boundname ) );
|
||||
if ( lol_get( frame->args, 1 ) )
|
||||
list_free( evaluate_rule( list_front( bind_rule ), frame ) );
|
||||
{
|
||||
OBJECT * rulename = list_front( bind_rule );
|
||||
list_free( evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ) );
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
frame_free( frame );
|
||||
|
||||
Reference in New Issue
Block a user