diff --git a/src/code/amd64.c b/src/code/amd64.c index adee98c039370da1c2316d998947a3813f96fde3..744fcb75a10d1e5825493cf92edc0192a8c960d3 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -3058,7 +3058,37 @@ void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c) ins_f_byte(F_MARK); ins_f_byte_with_2_args(F_EXTERNAL, b, c); return; - + case F_PRIVATE_TYPED_GLOBAL: + /* b -> off, c -> type */ + ins_debug_instr_prologue(a-F_OFFSET, b, c); + amd64_load_sp_reg(); + if( c < MIN_REF_TYPE ) + { + /* really: int or float. And right now, only float */ + amd64_get_storage( P_REG_RBX, b ); + mov_mem_reg( P_REG_RBX, 0, P_REG_RBX ); + mov_imm_mem( c, sp_reg, 0 ); + mov_reg_mem( P_REG_RBX, sp_reg, 8 ); + amd64_add_sp(1); + } + else + { + LABELS(); + /* one of the refcounted types. */ + amd64_get_storage( P_REG_RBX, b ); + mov_mem_reg( P_REG_RBX, 0, P_REG_RBX ); + test_reg( P_REG_RBX ); + jnz(&label_A); + amd64_push_int(0,1); + jmp(&label_B); + LABEL_A; + add_mem_imm( P_REG_RBX, 0, 1 ); + mov_imm_mem( c, sp_reg, 0 ); + mov_reg_mem( P_REG_RBX, sp_reg, 8 ); + amd64_add_sp(1); + LABEL_B; + } + return; case F_ADD_LOCAL_INT: case F_ADD_LOCAL_INT_AND_POP: { diff --git a/src/docode.c b/src/docode.c index 2c4c7f623d62650f0662f4149c675881e4005e95..7692288baf4e9b79cd0e7ab91b15b50ffcdacc76 100644 --- a/src/docode.c +++ b/src/docode.c @@ -688,11 +688,13 @@ static void emit_global( int n ) && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) && !IDENTIFIER_IS_ALIAS(id->identifier_flags) && IDENTIFIER_IS_VARIABLE(id->identifier_flags) - && !ref->inherit_offset - && id->run_time_type == PIKE_T_MIXED ) + && !ref->inherit_offset) { /* fprintf( stderr, "private global %d\n", (INT32)id->func.offset ); */ - emit1(F_PRIVATE_GLOBAL, id->func.offset); + if( id->run_time_type == PIKE_T_MIXED ) + emit1(F_PRIVATE_GLOBAL, id->func.offset); + else + emit2(F_PRIVATE_TYPED_GLOBAL, id->func.offset, id->run_time_type); } else emit1(F_GLOBAL, n); diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 85d61425c8396bcc3ee78330353ef0473f275f1e..8853b6c27d55639b72ad9ca044fb8cdaca178cc3 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -365,6 +365,42 @@ OPCODE1(F_PRIVATE_GLOBAL, "global <private>", I_UPDATE_SP, { print_return_value(); }); +OPCODE2(F_PRIVATE_TYPED_GLOBAL, "global <private>", I_UPDATE_SP, { + LOCAL_VAR(struct object *co); + LOCAL_VAR(void *ptr); + + co = Pike_fp->current_object; + ptr = (void *)(co->storage + Pike_fp->context->storage_offset + arg1); + if( arg2 < MIN_REF_TYPE ) + { +#if SIZEOF_FLOAT_TYPE != SIZEOF_INT_TYPE + if( UNLIKELY(arg2)==PIKE_T_INT ) + push_integer( *(INT_TYPE*)ptr ); + else + push_float( *(FLOAT_TYPE*)ptr ); +#else + SET_SVAL_TYPE_SUBTYPE(Pike_sp[0],arg2,0); + Pike_sp[0].u.integer = *(INT_TYPE*)ptr; + Pike_sp++; +#endif + } + else + { + INT32 *refs = *(INT32**)ptr; + if( !refs ) + push_undefined(); + else + { + struct svalue tmp; + SET_SVAL_TYPE_SUBTYPE(tmp,arg2,0); + tmp.u.refs = refs; + push_svalue(&tmp); + } + } + + print_return_value(); +}); + OPCODE2_TAIL(F_MARK_AND_EXTERNAL, "mark & external", I_UPDATE_SP|I_UPDATE_M_SP, { *(Pike_mark_sp++)=Pike_sp; @@ -1086,8 +1122,9 @@ OPCODE1(F_ASSIGN_GLOBAL_AND_POP, "assign global and pop", I_UPDATE_SP, { }); OPCODE1(F_ASSIGN_PRIVATE_GLOBAL_AND_POP, "assign private global and pop", I_UPDATE_SP, { - struct svalue *tmp; - struct object *co = Pike_fp->current_object; + LOCAL_VAR(struct svalue *tmp); + LOCAL_VAR(struct object *co); + co = Pike_fp->current_object; if(!co->prog) /* note: generate an error. */ object_low_set_index(co,0,0); tmp = (struct svalue *)(co->storage + Pike_fp->context->storage_offset + arg1); @@ -1096,8 +1133,9 @@ OPCODE1(F_ASSIGN_PRIVATE_GLOBAL_AND_POP, "assign private global and pop", I_UPDA }); OPCODE1(F_ASSIGN_PRIVATE_GLOBAL, "assign private global", I_UPDATE_SP, { - struct svalue *tmp; - struct object *co = Pike_fp->current_object; + LOCAL_VAR(struct svalue *tmp); + LOCAL_VAR(struct object *co); + co = Pike_fp->current_object; if(!co->prog) /* note: generate an error. */ object_low_set_index(co,0,0); tmp = (struct svalue *)(Pike_fp->current_object->storage + Pike_fp->context->storage_offset + arg1); @@ -1105,7 +1143,7 @@ OPCODE1(F_ASSIGN_PRIVATE_GLOBAL, "assign private global", I_UPDATE_SP, { }); OPCODE2(F_ASSIGN_GLOBAL_NUMBER_AND_POP, "assign global number and pop", 0, { - struct svalue tmp; + LOCAL_VAR(struct svalue tmp); SET_SVAL(tmp,PIKE_T_INT,0,integer,arg2); object_low_set_index(Pike_fp->current_object, arg1 + Pike_fp->context->identifier_level,