pike.git/src/docode.c:671: Inside #if defined(PIKE_DEBUG)
}
if (num_args != expected_args)
Pike_fatal ("Wrong number of args to o_range opcode. Expected %d, got %d.\n",
expected_args, num_args);
}
#endif
emit1 (F_RANGE, bound_types);
}
+ static void emit_global( int n )
+ {
+ struct compilation *c = THIS_COMPILATION;
+ struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n);
+ struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref);
+ if( (ref->id_flags & (ID_PRIVATE|ID_FINAL))
+ && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF)
+ && IDENTIFIER_IS_VARIABLE(id->identifier_flags)
+ && !ref->inherit_offset
+ && id->run_time_type == PIKE_T_MIXED )
+ {
+ /* fprintf( stderr, "private global %d\n", (INT32)id->func.offset ); */
+ emit1(F_PRIVATE_GLOBAL, id->func.offset);
+ }
+ else
+ emit1(F_GLOBAL, n);
+ }
+
+ static void emit_assign_global( int n, int and_pop )
+ {
+ struct compilation *c = THIS_COMPILATION;
+ struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n);
+ struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref);
+
+ if( (ref->id_flags & (ID_PRIVATE|ID_FINAL))
+ && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF)
+ && !ref->inherit_offset
+ && id->run_time_type == PIKE_T_MIXED )
+ {
+ /* fprintf( stderr, "assign private global and pop %d\n", */
+ /* (INT32)id->func.offset ); */
+ emit1((and_pop?F_ASSIGN_PRIVATE_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_GLOBAL),
+ id->func.offset);
+ }
+ else
+ {
+ emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n);
+ }
+ }
+
static void emit_multi_assign(node *vals, node *vars, int no)
{
struct compilation *c = THIS_COMPILATION;
node *var;
node *val;
node **valp = my_get_arg(&vals, no);
if (!vars && (!valp || !*valp)) return;
if (!(vars && valp && (val = *valp))) {
yyerror("Argument count mismatch for multi-assignment.\n");
pike.git/src/docode.c:719:
/* FIXME: Make special case for F_EXTERNAL */
case F_IDENTIFIER:
if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program,
var->u.id.number)->identifier_flags))
{
yyerror("Cannot assign functions or constants.\n");
}else{
code_expression(val, 0, "RHS");
emit_multi_assign(vals, vars, no+1);
- emit1(F_ASSIGN_GLOBAL_AND_POP, var->u.id.number);
+ emit_assign_global( var->u.id.number, 1 );
}
break;
case F_GET_SET:
{
/* Check for the setter function. */
struct program_state *state = Pike_compiler;
int program_id = var->u.integer.a;
int level = 0;
while (state && (state->new_program->id != program_id)) {
pike.git/src/docode.c:778:
case F_EXTERNAL:
/* Check that it is in this context */
if(Pike_compiler ->new_program->id == var->u.integer.a)
{
/* Check that it is a variable */
if(var->u.integer.b != IDREF_MAGIC_THIS &&
IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, var->u.integer.b)->identifier_flags))
{
code_expression(val, 0, "RHS");
emit_multi_assign(vals, vars, no+1);
- emit1(F_ASSIGN_GLOBAL_AND_POP, var->u.integer.b);
+ emit_assign_global( var->u.integer.b, 1 );
break;
}
}
/* fall through */
default:
normal_assign:
do_docode(var, DO_LVALUE);
if(do_docode(val, 0) != 1) yyerror("RHS is void!");
emit_multi_assign(vals, vars, no+1);
pike.git/src/docode.c:984:
struct svalue *s = &state->new_program->
constants[id->func.const_info.offset].sval;
if (TYPEOF(*s) == T_PROGRAM &&
s->u.program->flags & PROGRAM_USES_PARENT) {
/* Program using parent. Convert to an LFUN. */
emit1(F_LFUN, n->u.integer.b);
} else {
emit1(F_CONSTANT, id->func.const_info.offset);
}
}else{
- emit1(F_GLOBAL, n->u.integer.b);
+ emit_global( n->u.integer.b );
}
}
}
return 1;
case F_THIS:
{
int level = 0;
struct program_state *state = Pike_compiler;
int inh = n->u.integer.b;
pike.git/src/docode.c:1264:
case F_LSH:
case F_RSH:
case F_ADD:
case F_MOD:
case F_SUBTRACT:
case F_DIVIDE:
case F_MULTIPLY:
if(node_is_eq(CDR(n),CAAR(n)))
{
int num_args;
- tmp1=do_docode(CDR(n),DO_LVALUE);
+ /* tmp1=do_docode(CDR(n),DO_LVALUE); */
if(match_types(CDR(n)->type, array_type_string) ||
match_types(CDR(n)->type, string_type_string) ||
match_types(CDR(n)->type, object_type_string) ||
match_types(CDR(n)->type, multiset_type_string) ||
match_types(CDR(n)->type, mapping_type_string))
{
-
+ do_docode(CDR(n),DO_LVALUE);
num_args = do_docode(CDAR(n), 0);
switch (num_args)
{
case 0: emit0(F_LTOSVAL_AND_FREE); break;
case 1: emit0(F_LTOSVAL2_AND_FREE); break;
case 2: emit0(F_LTOSVAL3_AND_FREE); break;
#ifdef PIKE_DEBUG
default:
Pike_fatal("Arglebargle glop-glyf?\n");
#endif
}
}else{
-
+ goto do_not_suboptimize_assign;
emit0(F_LTOSVAL);
num_args = do_docode(CDAR(n), 0);
}
if (CAR (n)->token == F_RANGE)
emit_range (CAR (n) DO_IF_DEBUG (COMMA num_args));
else
emit0(CAR(n)->token);
emit0(n->token);
pike.git/src/docode.c:1307:
(TYPEOF(CAAR(n)->u.sval) == T_FUNCTION) &&
(SUBTYPEOF(CAAR(n)->u.sval) == FUNCTION_BUILTIN) &&
(CAAR(n)->u.sval.u.efun->function != f_map) &&
(CAAR(n)->u.sval.u.efun->function != f_filter)) {
/* efuns typically don't access object variables. */
node *args = CDAR(n);
if (args) {
node **arg = my_get_arg(&args, 0);
if (arg && node_is_eq(CDR(n), *arg) &&
!(args->tree_info & OPT_ASSIGNMENT)) {
+ if(match_types(CDR(n)->type, array_type_string) ||
+ match_types(CDR(n)->type, string_type_string) ||
+ match_types(CDR(n)->type, object_type_string) ||
+ match_types(CDR(n)->type, multiset_type_string) ||
+ match_types(CDR(n)->type, mapping_type_string))
+ {
/* First arg is the lvalue.
*
* We optimize this to allow for destructive operations.
*/
int no = 0;
tmp1 = do_docode(CDR(n), DO_LVALUE);
emit0(F_MARK_AND_CONST0);
PUSH_CLEANUP_FRAME(do_pop_mark, 0);
while ((arg = my_get_arg(&args, ++no)) && *arg) {
do_docode(*arg, 0);
}
tmp1=store_constant(&CAAR(n)->u.sval,
!(CAAR(n)->tree_info & OPT_EXTERNAL_DEPEND),
CAAR(n)->name);
emit1(F_LTOSVAL_CALL_BUILTIN_AND_ASSIGN, DO_NOT_WARN((INT32)tmp1));
POP_AND_DONT_CLEANUP;
return 1;
}
}
}
-
+ }
/* FALL_THROUGH */
default:
-
+ do_not_suboptimize_assign:
switch(CDR(n)->token)
{
-
+ case F_GLOBAL:
+ if(CDR(n)->u.integer.b) goto normal_assign;
+ code_expression(CAR(n), 0, "RHS");
+ emit_assign_global( CDR(n)->u.integer.a, flags & DO_POP );
+ break;
case F_LOCAL:
if(CDR(n)->u.integer.a >=
find_local_frame(CDR(n)->u.integer.b)->max_number_of_locals)
yyerror("Illegal to use local variable here.");
if(CDR(n)->u.integer.b) goto normal_assign;
if (CDR(n)->node_info & OPT_ASSIGNMENT) {
/* Initialize. */
emit0(F_CONST0);
pike.git/src/docode.c:1355:
CDR(n)->u.integer.a );
break;
/* FIXME: Make special case for F_EXTERNAL */
case F_IDENTIFIER:
if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.id.number)->identifier_flags))
{
yyerror("Cannot assign functions or constants.\n");
}else{
code_expression(CAR(n), 0, "RHS");
- emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
- CDR(n)->u.id.number);
+ emit_assign_global( CDR(n)->u.id.number, flags & DO_POP );
}
break;
case F_GET_SET:
{
/* Check for the setter function. */
struct program_state *state = Pike_compiler;
int program_id = CDR(n)->u.integer.a;
int level = 0;
while (state && (state->new_program->id != program_id)) {
pike.git/src/docode.c:1428:
/* FALL_THROUGH */
case F_EXTERNAL:
/* Check that it is in this context */
if(Pike_compiler ->new_program->id == CDR(n)->u.integer.a)
{
/* Check that it is a variable */
if(CDR(n)->u.integer.b != IDREF_MAGIC_THIS &&
IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.integer.b)->identifier_flags))
{
code_expression(CAR(n), 0, "RHS");
- emit1(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
- CDR(n)->u.integer.b);
+ emit_assign_global(CDR(n)->u.integer.b, flags & DO_POP );
break;
}
}
/* fall through */
default:
normal_assign:
tmp1=do_docode(CDR(n),DO_LVALUE);
if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!");
emit0(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
pike.git/src/docode.c:2763:
if(flags & WANT_LVALUE)
{
yyerror("Cannot assign functions.\n");
}else{
if (id->identifier_flags & IDENTIFIER_HAS_BODY)
/* Only use this opcode when it's certain that the result
* can't zero, i.e. when we know the function isn't just a
* prototype. */
emit1(F_LFUN,n->u.id.number);
else
- emit1(F_GLOBAL,n->u.id.number);
+ emit_global(n->u.id.number);
}
}else{
if(flags & WANT_LVALUE)
{
emit1(F_GLOBAL_LVALUE,n->u.id.number);
return 2;
}else{
- emit1(F_GLOBAL,n->u.id.number);
+ emit_global(n->u.id.number);
}
}
return 1;
}
case F_VAL_LVAL:
ret = do_docode(CAR(n),flags);
return ret + do_docode(CDR(n), flags | DO_LVALUE);
case F_AUTO_MAP: