2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-13 12:22:17 +00:00

Small optimization for [ on target return var ].

[SVN r83919]
This commit is contained in:
Steven Watanabe
2013-04-15 22:55:49 +00:00
parent 5a3c570eda
commit 700087b6cb

View File

@@ -93,6 +93,7 @@ void backtrace_line( FRAME * );
#define INSTR_SET_ON 36
#define INSTR_APPEND_ON 37
#define INSTR_DEFAULT_ON 38
#define INSTR_GET_ON 65
#define INSTR_CALL_RULE 39
@@ -2482,12 +2483,62 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location )
}
else if ( parse->type == PARSE_ON )
{
int end = compile_new_label( c );
compile_parse( parse->left, c, RESULT_STACK );
compile_emit_branch( c, INSTR_PUSH_ON, end );
compile_parse( parse->right, c, RESULT_STACK );
compile_emit( c, INSTR_POP_ON, 0 );
compile_set_label( c, end );
if ( parse->right->type == PARSE_APPEND &&
parse->right->left->type == PARSE_NULL &&
parse->right->right->type == PARSE_LIST )
{
/* [ on $(target) return $(variable) ] */
PARSE * value = parse->right->right;
OBJECT * const o = value->string;
char const * s = object_str( o );
VAR_PARSE_GROUP * group;
OBJECT * varname = 0;
current_file = object_str( value->file );
current_line = value->line;
group = parse_expansion( &s );
if ( group->elems->size == 1 )
{
VAR_PARSE * one = dynamic_array_at( VAR_PARSE *, group->elems, 0 );
if ( one->type == VAR_PARSE_TYPE_VAR )
{
VAR_PARSE_VAR * var = ( VAR_PARSE_VAR * )one;
if ( var->modifiers->size == 0 && !var->subscript && var->name->elems->size == 1 )
{
VAR_PARSE * name = dynamic_array_at( VAR_PARSE *, var->name->elems, 0 );
if ( name->type == VAR_PARSE_TYPE_STRING )
{
varname = ( ( VAR_PARSE_STRING * )name )->s;
}
}
}
}
if ( varname )
{
/* We have one variable with a fixed name and no modifiers. */
compile_parse( parse->left, c, RESULT_STACK );
compile_emit( c, INSTR_GET_ON, compile_emit_constant( c, varname ) );
}
else
{
/* Too complex. Fall back on push/pop. */
int end = compile_new_label( c );
compile_parse( parse->left, c, RESULT_STACK );
compile_emit_branch( c, INSTR_PUSH_ON, end );
var_parse_group_compile( group, c );
compile_emit( c, INSTR_POP_ON, 0 );
compile_set_label( c, end );
}
var_parse_group_free( group );
}
else
{
int end = compile_new_label( c );
compile_parse( parse->left, c, RESULT_STACK );
compile_emit_branch( c, INSTR_PUSH_ON, end );
compile_parse( parse->right, c, RESULT_STACK );
compile_emit( c, INSTR_POP_ON, 0 );
compile_set_label( c, end );
}
adjust_result( c, RESULT_STACK, result_location );
}
else if ( parse->type == PARSE_RULE )
@@ -3912,6 +3963,35 @@ LIST * function_run( FUNCTION * function_, FRAME * frame, STACK * s )
break;
}
/* [ on $(target) return $(variable) ] */
case INSTR_GET_ON:
{
LIST * targets = stack_pop( s );
LIST * result = L0;
if ( !list_empty( targets ) )
{
OBJECT * varname = function->constants[ code->arg ];
TARGET * t = bindtarget( list_front( targets ) );
SETTINGS * s = t->settings;
int found = 0;
for ( ; s != 0; s = s->next )
{
if ( object_equal( s->symbol, varname ) )
{
result = s->value;
found = 1;
break;
}
}
if ( !found )
{
result = var_get( frame->module, varname ) ;
}
}
stack_push( s, list_copy( result ) );
break;
}
/*
* Variable setting
*/