e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
c6c01a2003-11-14Martin Stjernholm || $Id: opcodes.c,v 1.155 2003/11/14 09:06:06 mast Exp $
e576bb2002-10-11Martin Nilsson */
aedfb12002-10-09Martin Nilsson 
b788cd1998-07-04Henrik Grubbström (Grubba) #include "global.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "mapping.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
98f2b11998-02-19Fredrik Hübinette (Hubbe) #include "cyclic.h" #include "builtin_functions.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
6ad2372002-05-11Martin Nilsson #define sp Pike_sp
c6c01a2003-11-14Martin Stjernholm RCSID("$Id: opcodes.c,v 1.155 2003/11/14 09:06:06 mast Exp $");
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) {
7e97c31999-01-21Fredrik Hübinette (Hubbe) #ifdef PIKE_SECURITY if(what->type <= MAX_COMPLEX) if(!CHECK_DATA_SECURITY(what->u.array, SECURITY_BIT_INDEX))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Index permission denied.\n");
7e97c31999-01-21Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(what->type) { case T_ARRAY: simple_array_index_no_free(to,what->u.array,ind); break; case T_MAPPING: mapping_index_no_free(to,what->u.mapping,ind); break; case T_OBJECT: object_index_no_free(to, what->u.object, ind); break;
e3f1e82003-04-28Martin Stjernholm  case T_MULTISET: { int i=multiset_member(what->u.multiset, ind);
5267b71995-08-09Fredrik Hübinette (Hubbe)  to->type=T_INT;
2843b82003-08-05Martin Stjernholm  to->subtype=i ? 0 : NUMBER_UNDEFINED;
5267b71995-08-09Fredrik Hübinette (Hubbe)  to->u.integer=i; break;
e3f1e82003-04-28Martin Stjernholm  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_STRING: if(ind->type==T_INT) {
b99d882003-05-15Martin Stjernholm  ptrdiff_t len = what->u.string->len; INT_TYPE p = ind->u.integer; INT_TYPE i = p < 0 ? p + len : p; if(i<0 || i>=len)
f0e76d1999-08-22Fredrik Noring  {
b99d882003-05-15Martin Stjernholm  if(len == 0)
e3f1e82003-04-28Martin Stjernholm  Pike_error("Attempt to index the empty string with %"PRINTPIKEINT"d.\n", i);
f0e76d1999-08-22Fredrik Noring  else
e3f1e82003-04-28Martin Stjernholm  Pike_error("Index %"PRINTPIKEINT"d is out of string range "
b99d882003-05-15Martin Stjernholm  "%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n", i, -len, len - 1);
f0e76d1999-08-22Fredrik Noring  } else
db4a401998-10-09Fredrik Hübinette (Hubbe)  i=index_shared_string(what->u.string,i);
5267b71995-08-09Fredrik Hübinette (Hubbe)  to->type=T_INT; to->subtype=NUMBER_NUMBER; to->u.integer=i; break; }else{
e3f1e82003-04-28Martin Stjernholm  if (ind->type == T_STRING && !ind->u.string->size_shift) Pike_error ("Expected integer as string index, got \"%s\".\n", ind->u.string->str); else Pike_error ("Expected integer as string index, got %s.\n", get_name_of_type (ind->type));
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
3a1bef1998-06-07Henrik Grubbström (Grubba)  case T_PROGRAM: program_index_no_free(to, what->u.program, ind); break; case T_FUNCTION: { struct program *p = program_from_svalue(what); if (p) { program_index_no_free(to, p, ind); break; } } /* FALL THROUGH */
136bad2003-08-13Henrik Grubbström (Grubba) #ifdef AUTO_BIGNUM case T_INT: if (ind->type == T_STRING) { INT_TYPE val = what->u.integer; convert_svalue_to_bignum(what); index_no_free(to, what, ind); if(IS_UNDEFINED(to)) { if (val) { if (!ind->u.string->size_shift) Pike_error("Indexing the integer %"PRINTPIKEINT"d " "with unknown method \"%s\".\n", val, ind->u.string->str); else Pike_error("Indexing the integer %"PRINTPIKEINT"d " "with a wide string.\n", val); } else { if(!ind->u.string->size_shift) Pike_error("Indexing the NULL value with \"%s\".\n", ind->u.string->str); else Pike_error("Indexing the NULL value with a wide string.\n"); } } break; } /* FALL_THROUGH */ #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
e3f1e82003-04-28Martin Stjernholm  if (ind->type == T_INT) Pike_error ("Cannot index %s with %"PRINTPIKEINT"d.\n",
136bad2003-08-13Henrik Grubbström (Grubba)  (what->type == T_INT && !what->u.integer)? "the NULL value":get_name_of_type(what->type), ind->u.integer);
e3f1e82003-04-28Martin Stjernholm  else if (ind->type == T_FLOAT) Pike_error ("Cannot index %s with %"PRINTPIKEFLOAT"g.\n",
136bad2003-08-13Henrik Grubbström (Grubba)  (what->type == T_INT && !what->u.integer)? "the NULL value":get_name_of_type(what->type), ind->u.float_number);
e3f1e82003-04-28Martin Stjernholm  else if (ind->type == T_STRING && !ind->u.string->size_shift)
136bad2003-08-13Henrik Grubbström (Grubba)  Pike_error ("Cannot index %s with \"%s\".\n", (what->type == T_INT && !what->u.integer)? "the NULL value":get_name_of_type(what->type),
e3f1e82003-04-28Martin Stjernholm  ind->u.string->str); else
136bad2003-08-13Henrik Grubbström (Grubba)  Pike_error ("Cannot index %s with %s.\n", (what->type == T_INT && !what->u.integer)? "the NULL value":get_name_of_type(what->type),
e3f1e82003-04-28Martin Stjernholm  get_name_of_type (ind->type));
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
be478c1997-08-30Henrik Grubbström (Grubba) void o_index(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
de2a581997-09-28Fredrik Hübinette (Hubbe)  struct svalue s; index_no_free(&s,sp-2,sp-1); pop_n_elems(2); *sp=s;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
5683de1995-11-06Fredrik Hübinette (Hubbe)  sp++;
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
c6f8f92002-12-07Henrik Grubbström (Grubba) /*! @class MasterObject */ /*! @decl object cast_to_object(string str, string|void current_file) *! *! Called by the Pike runtime to cast strings to objects. *! *! @param str *! String to cast to object. *! *! @param current_file *! Filename of the file that attempts to perform the cast. *! *! @returns *! Returns the resulting object. *! *! @seealso *! @[cast_to_program()] */ /*! @decl program cast_to_program(string str, string|void current_file) *! *! Called by the Pike runtime to cast strings to programs. *! *! @param str *! String to cast to object. *! *! @param current_file *! Filename of the file that attempts to perform the cast. *! *! @returns *! Returns the resulting program. *! *! @seealso *! @[cast_to_object()] */ /*! @endclass */
0232d22001-06-17Henrik Grubbström (Grubba) /* Special case for casting to int. */ void o_cast_to_int(void) { switch(sp[-1].type) { case T_OBJECT: { struct pike_string *s;
de56ec2003-02-08Martin Stjernholm  REF_MAKE_CONST_STRING(s, "int");
0232d22001-06-17Henrik Grubbström (Grubba)  push_string(s); if(!sp[-2].u.object->prog) Pike_error("Cast called on destructed object.\n"); if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1) Pike_error("No cast method in object.\n"); apply_lfun(sp[-2].u.object, LFUN_CAST, 1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--; dmalloc_touch_svalue(sp); }
7f94c22001-06-17Henrik Grubbström (Grubba)  if(sp[-1].type != PIKE_T_INT) { if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog) { int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE); if( f != -1) { struct pike_string *s;
de56ec2003-02-08Martin Stjernholm  REF_MAKE_CONST_STRING(s, "int");
7f94c22001-06-17Henrik Grubbström (Grubba)  push_string(s); apply_low(sp[-2].u.object, f, 1);
9f516a2001-12-16Martin Stjernholm  f=!UNSAFE_IS_ZERO(sp-1);
7f94c22001-06-17Henrik Grubbström (Grubba)  pop_stack(); if(f) return; } } Pike_error("Cast failed, wanted int, got %s\n", get_name_of_type(sp[-1].type)); }
0232d22001-06-17Henrik Grubbström (Grubba)  break;
7f94c22001-06-17Henrik Grubbström (Grubba) 
0232d22001-06-17Henrik Grubbström (Grubba)  case T_FLOAT: { int i=DO_NOT_WARN((int)(sp[-1].u.float_number)); #ifdef AUTO_BIGNUM if((i < 0 ? -i : i) < floor(fabs(sp[-1].u.float_number))) { /* Note: This includes the case when i = 0x80000000, i.e. the absolute value is not computable. */ convert_stack_top_to_bignum(); return; /* FIXME: OK to return? Cast tests below indicates we have to do this, at least for now... /Noring */ /* Yes, it is ok to return, it is actually an optimization :) * /Hubbe */ } else #endif /* AUTO_BIGNUM */ { sp[-1].type=T_INT; sp[-1].u.integer=i; } } break; case T_STRING: /* This can be here independently of AUTO_BIGNUM. Besides, we really want to reduce the number of number parsers around here. :) /Noring */ #ifdef AUTO_BIGNUM /* The generic function is rather slow, so I added this * code for benchmark purposes. :-) /per */ if( sp[-1].u.string->len < 10 && !sp[-1].u.string->size_shift ) { int i=atoi(sp[-1].u.string->str); free_string(sp[-1].u.string); sp[-1].type=T_INT; sp[-1].u.integer=i; } else convert_stack_top_string_to_inumber(10); return; /* FIXME: OK to return? Cast tests below indicates we have to do this, at least for now... /Noring */ /* Yes, it is ok to return, it is actually an optimization :) * /Hubbe */ #else { int i=STRTOL(sp[-1].u.string->str,0,10); free_string(sp[-1].u.string); sp[-1].type=T_INT; sp[-1].u.integer=i; } #endif /* AUTO_BIGNUM */ break; case PIKE_T_INT: break; default: Pike_error("Cannot cast %s to int.\n", get_name_of_type(sp[-1].type)); } }
c6f8f92002-12-07Henrik Grubbström (Grubba) /* Special case for casting to string. */
7f94c22001-06-17Henrik Grubbström (Grubba) void o_cast_to_string(void) { char buf[200]; switch(sp[-1].type) { case PIKE_T_STRING: return; case T_OBJECT: { struct pike_string *s;
de56ec2003-02-08Martin Stjernholm  REF_MAKE_CONST_STRING(s, "string");
7f94c22001-06-17Henrik Grubbström (Grubba)  push_string(s); if(!sp[-2].u.object->prog) Pike_error("Cast called on destructed object.\n"); if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1) Pike_error("No cast method in object.\n"); apply_lfun(sp[-2].u.object, LFUN_CAST, 1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--; dmalloc_touch_svalue(sp); } if(sp[-1].type != PIKE_T_STRING) { if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog) { int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE); if( f != -1) { struct pike_string *s;
de56ec2003-02-08Martin Stjernholm  REF_MAKE_CONST_STRING(s, "string");
7f94c22001-06-17Henrik Grubbström (Grubba)  push_string(s); apply_low(sp[-2].u.object, f, 1);
9f516a2001-12-16Martin Stjernholm  f=!UNSAFE_IS_ZERO(sp-1);
7f94c22001-06-17Henrik Grubbström (Grubba)  pop_stack(); if(f) return; } } Pike_error("Cast failed, wanted string, got %s\n", get_name_of_type(sp[-1].type)); } return; case T_ARRAY: { int i; struct array *a = sp[-1].u.array; struct pike_string *s; int shift = 0; for(i = a->size; i--; ) { unsigned INT32 val; if (a->item[i].type != T_INT) { Pike_error("cast: Item %d is not an integer.\n", i); } val = (unsigned INT32)a->item[i].u.integer; if (val > 0xff) { shift = 1; if (val > 0xffff) { shift = 2; while(i--) if (a->item[i].type != T_INT) Pike_error("cast: Item %d is not an integer.\n", i); break; } while(i--) { if (a->item[i].type != T_INT) { Pike_error("cast: Item %d is not an integer.\n", i); } val = (unsigned INT32)a->item[i].u.integer; if (val > 0xffff) { shift = 2; while(i--) if (a->item[i].type != T_INT) Pike_error("cast: Item %d is not an integer.\n", i); break; } } break; } } s = begin_wide_shared_string(a->size, shift); switch(shift) { case 0: for(i = a->size; i--; ) { s->str[i] = a->item[i].u.integer; } break; case 1: { p_wchar1 *str1 = STR1(s); for(i = a->size; i--; ) { str1[i] = a->item[i].u.integer; } } break; case 2: { p_wchar2 *str2 = STR2(s); for(i = a->size; i--; ) { str2[i] = a->item[i].u.integer; } } break; default: free_string(end_shared_string(s));
5aad932002-08-15Marcus Comstedt  Pike_fatal("cast: Bad shift: %d.\n", shift);
7f94c22001-06-17Henrik Grubbström (Grubba)  break; } s = end_shared_string(s); pop_stack(); push_string(s); } return; case T_INT:
de4b122003-01-26Mirar (Pontus Hagland)  sprintf(buf, "%"PRINTPIKEINT"d", sp[-1].u.integer);
7f94c22001-06-17Henrik Grubbström (Grubba)  break; case T_FLOAT: sprintf(buf, "%f", (double)sp[-1].u.float_number); break; default: Pike_error("Cannot cast %s to string.\n", get_name_of_type(sp[-1].type)); } sp[-1].type = PIKE_T_STRING; sp[-1].u.string = make_shared_string(buf); }
d68a072001-02-20Henrik Grubbström (Grubba) void o_cast(struct pike_type *type, INT32 run_time_type)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_type != sp[-1].type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_type == T_MIXED)
07c0731996-06-21Fredrik Hübinette (Hubbe)  return;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(sp[-1].type == T_OBJECT)
07c0731996-06-21Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  s=describe_type(type);
07c0731996-06-21Fredrik Hübinette (Hubbe)  push_string(s); if(!sp[-2].u.object->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cast called on destructed object.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("No cast method in object.\n");
07c0731996-06-21Fredrik Hübinette (Hubbe)  apply_lfun(sp[-2].u.object, LFUN_CAST, 1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  }else
07c0731996-06-21Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(run_time_type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7e97c31999-01-21Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot perform cast to that type.\n");
7e97c31999-01-21Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_MIXED:
e97d731998-02-27Fredrik Hübinette (Hubbe)  return;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) 
06f6112000-01-27Fredrik Hübinette (Hubbe)  case T_MULTISET: switch(sp[-1].type) { case T_ARRAY:
a96ce92000-04-19Fredrik Hübinette (Hubbe)  { extern void f_mkmultiset(INT32);
06f6112000-01-27Fredrik Hübinette (Hubbe)  f_mkmultiset(1); break;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  }
06f6112000-01-27Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to multiset.\n",get_name_of_type(sp[-1].type));
06f6112000-01-27Fredrik Hübinette (Hubbe)  } break;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  case T_MAPPING: switch(sp[-1].type) { case T_ARRAY: {
505aec2000-11-29Mirar (Pontus Hagland)  struct array *a=sp[-1].u.array; struct array *b; struct mapping *m; INT32 i; m=allocate_mapping(a->size); /* MAP_SLOTS(a->size) */ push_mapping(m); for (i=0; i<a->size; i++) { if (ITEM(a)[i].type!=T_ARRAY)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cast array to mapping: "
505aec2000-11-29Mirar (Pontus Hagland)  "element %d is not an array\n", i); b=ITEM(a)[i].u.array; if (b->size!=2)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cast array to mapping: "
505aec2000-11-29Mirar (Pontus Hagland)  "element %d is not an array of size 2\n", i); mapping_insert(m,ITEM(b)+0,ITEM(b)+1); } stack_swap(); pop_n_elems(1); break;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  } default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to mapping.\n",get_name_of_type(sp[-1].type));
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  } break;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_ARRAY: switch(sp[-1].type) { case T_MAPPING: { struct array *a=mapping_to_array(sp[-1].u.mapping); pop_stack(); push_array(a); break; } case T_STRING: f_values(1); break; case T_MULTISET: f_indices(1); break; default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to array.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
98f2b11998-02-19Fredrik Hübinette (Hubbe) 
0232d22001-06-17Henrik Grubbström (Grubba)  case T_INT: o_cast_to_int();
7f94c22001-06-17Henrik Grubbström (Grubba)  return;
98f2b11998-02-19Fredrik Hübinette (Hubbe) 
7f94c22001-06-17Henrik Grubbström (Grubba)  case T_STRING: o_cast_to_string(); return;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_FLOAT: {
3ef2481999-10-22Fredrik Noring  FLOAT_TYPE f = 0.0;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(sp[-1].type) { case T_INT: f=(FLOAT_TYPE)(sp[-1].u.integer); break; case T_STRING:
a5cd6a2001-09-24Henrik Grubbström (Grubba)  f = (FLOAT_TYPE)STRTOD_PCHARP(MKPCHARP(sp[-1].u.string->str, sp[-1].u.string->size_shift), 0);
98f2b11998-02-19Fredrik Hübinette (Hubbe)  free_string(sp[-1].u.string); break; default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to float.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } sp[-1].type=T_FLOAT; sp[-1].u.float_number=f;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_OBJECT: switch(sp[-1].type) {
807d072002-12-01Martin Stjernholm  case T_STRING: { struct pike_string *file; INT32 lineno; if(Pike_fp->pc && (file = low_get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno))) { push_string(file);
98f2b11998-02-19Fredrik Hübinette (Hubbe)  }else{ push_int(0); }
c6f8f92002-12-07Henrik Grubbström (Grubba)  /* FIXME: Ought to allow compile_handler to override. */
98f2b11998-02-19Fredrik Hübinette (Hubbe)  APPLY_MASTER("cast_to_object",2); return;
807d072002-12-01Martin Stjernholm  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  case T_FUNCTION:
a253f42001-03-31Henrik Grubbström (Grubba)  if (Pike_sp[-1].subtype == FUNCTION_BUILTIN) { Pike_error("Cannot cast builtin functions to object.\n");
493b222003-01-15Henrik Grubbström (Grubba)  } else if (Pike_sp[-1].u.object->prog == pike_trampoline_program) { ref_push_object(((struct pike_trampoline *) (Pike_sp[-1].u.object->storage))-> frame->current_object);
0d0bab2003-04-27Martin Stjernholm  stack_pop_keep_top();
a253f42001-03-31Henrik Grubbström (Grubba)  } else {
e9ecc02001-03-31Henrik Grubbström (Grubba)  Pike_sp[-1].type = T_OBJECT;
a253f42001-03-31Henrik Grubbström (Grubba)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  break;
569c171998-02-27Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to object.\n",get_name_of_type(sp[-1].type));
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } break; case T_PROGRAM:
0e70221998-04-05Fredrik Hübinette (Hubbe)  switch(sp[-1].type) {
807d072002-12-01Martin Stjernholm  case T_STRING: { struct pike_string *file; INT32 lineno; if(Pike_fp->pc && (file = low_get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno))) { push_string(file);
0e70221998-04-05Fredrik Hübinette (Hubbe)  }else{ push_int(0); }
c6f8f92002-12-07Henrik Grubbström (Grubba)  /* FIXME: Ought to allow compile_handler to override. */
0e70221998-04-05Fredrik Hübinette (Hubbe)  APPLY_MASTER("cast_to_program",2); return;
807d072002-12-01Martin Stjernholm  }
0e70221998-04-05Fredrik Hübinette (Hubbe)  case T_FUNCTION:
0a9e131997-02-16Fredrik Hübinette (Hubbe)  {
0e70221998-04-05Fredrik Hübinette (Hubbe)  struct program *p=program_from_function(sp-1); if(p) {
d6ac731998-04-20Henrik Grubbström (Grubba)  add_ref(p);
0e70221998-04-05Fredrik Hübinette (Hubbe)  pop_stack(); push_program(p); }else{ pop_stack(); push_int(0); }
0a9e131997-02-16Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  return;
0e70221998-04-05Fredrik Hübinette (Hubbe)  default:
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot cast %s to a program.\n",get_name_of_type(sp[-1].type));
0e70221998-04-05Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_type != sp[-1].type)
110b3f1999-10-29Fredrik Hübinette (Hubbe)  { if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog) { int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE); if( f != -1) { push_text(get_name_of_type(run_time_type)); apply_low(sp[-2].u.object, f, 1);
9f516a2001-12-16Martin Stjernholm  f=!UNSAFE_IS_ZERO(sp-1);
110b3f1999-10-29Fredrik Hübinette (Hubbe)  pop_stack(); if(f) goto emulated_type_ok; } }
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cast failed, wanted %s, got %s\n",
110b3f1999-10-29Fredrik Hübinette (Hubbe)  get_name_of_type(run_time_type), get_name_of_type(sp[-1].type)); } emulated_type_ok:
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0252201999-07-27Mirar (Pontus Hagland)  if (!type) return;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  switch(run_time_type) { case T_ARRAY:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *itype;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  INT32 run_time_itype;
d68a072001-02-20Henrik Grubbström (Grubba)  push_type_value(itype = index_type(type, int_type_string, 0));
babd872001-02-23Henrik Grubbström (Grubba)  run_time_itype = compile_type_to_runtime_type(itype);
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(run_time_itype != T_MIXED)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
98f2b11998-02-19Fredrik Hübinette (Hubbe)  struct array *a; struct array *tmp=sp[-2].u.array; DECLARE_CYCLIC(); if((a=(struct array *)BEGIN_CYCLIC(tmp,0))) { ref_push_array(a); }else{
a5cd6a2001-09-24Henrik Grubbström (Grubba)  INT32 e;
2523ce2003-04-28Martin Stjernholm  TYPE_FIELD types = 0;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
7ea3341998-05-16Fredrik Hübinette (Hubbe)  struct svalue *save_sp=sp+1; #endif
98f2b11998-02-19Fredrik Hübinette (Hubbe)  push_array(a=allocate_array(tmp->size)); SET_CYCLIC_RET(a); for(e=0;e<a->size;e++) { push_svalue(tmp->item+e); o_cast(itype, run_time_itype);
2523ce2003-04-28Martin Stjernholm  stack_pop_to_no_free (ITEM(a) + e); types |= 1 << ITEM(a)[e].type;
98f2b11998-02-19Fredrik Hübinette (Hubbe)  }
2523ce2003-04-28Martin Stjernholm  a->type_field = types;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
7ea3341998-05-16Fredrik Hübinette (Hubbe)  if(save_sp!=sp)
5aad932002-08-15Marcus Comstedt  Pike_fatal("o_cast left stack droppings.\n");
7ea3341998-05-16Fredrik Hübinette (Hubbe) #endif
98f2b11998-02-19Fredrik Hübinette (Hubbe)  }
14bb592000-05-06Fredrik Hübinette (Hubbe)  END_CYCLIC();
98f2b11998-02-19Fredrik Hübinette (Hubbe)  assign_svalue(sp-3,sp-1); pop_stack();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
98f2b11998-02-19Fredrik Hübinette (Hubbe)  pop_stack();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  break; case T_MULTISET: {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *itype;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  INT32 run_time_itype;
d68a072001-02-20Henrik Grubbström (Grubba)  push_type_value(itype = key_type(type, 0));
babd872001-02-23Henrik Grubbström (Grubba)  run_time_itype = compile_type_to_runtime_type(itype);
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  if(run_time_itype != T_MIXED) { struct multiset *m;
5b15bb2001-12-10Martin Stjernholm #ifdef PIKE_NEW_MULTISETS struct multiset *tmp=sp[-2].u.multiset; #else
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  struct array *tmp=sp[-2].u.multiset->ind;
5b15bb2001-12-10Martin Stjernholm #endif
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  DECLARE_CYCLIC(); if((m=(struct multiset *)BEGIN_CYCLIC(tmp,0))) { ref_push_multiset(m); }else{ #ifdef PIKE_DEBUG struct svalue *save_sp=sp+1; #endif
5b15bb2001-12-10Martin Stjernholm  #ifdef PIKE_NEW_MULTISETS ptrdiff_t nodepos; if (multiset_indval (tmp)) Pike_error ("FIXME: Casting not implemented for multisets with values.\n"); push_multiset (m = allocate_multiset (multiset_sizeof (tmp), multiset_get_flags (tmp), multiset_get_cmp_less (tmp))); SET_CYCLIC_RET(m); if ((nodepos = multiset_first (tmp)) >= 0) { ONERROR uwp; SET_ONERROR (uwp, do_sub_msnode_ref, tmp); do { push_multiset_index (tmp, nodepos); o_cast(itype, run_time_itype); multiset_insert_2 (m, sp - 1, NULL, 0); pop_stack(); } while ((nodepos = multiset_next (tmp, nodepos)) >= 0); UNSET_ONERROR (uwp);
cf626e2003-08-26Henrik Grubbström (Grubba)  sub_msnode_ref (tmp);
5b15bb2001-12-10Martin Stjernholm  } #else /* PIKE_NEW_MULTISETS */ INT32 e; struct array *a;
2523ce2003-04-28Martin Stjernholm  TYPE_FIELD types = 0;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  push_multiset(m=allocate_multiset(a=allocate_array(tmp->size))); SET_CYCLIC_RET(m); for(e=0;e<a->size;e++) { push_svalue(tmp->item+e); o_cast(itype, run_time_itype);
2523ce2003-04-28Martin Stjernholm  stack_pop_to_no_free (ITEM(a) + e); types |= 1 << ITEM(a)[e].type;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  }
2523ce2003-04-28Martin Stjernholm  a->type_field = types;
5b15bb2001-12-10Martin Stjernholm  order_multiset(m); #endif
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG if(save_sp!=sp)
5aad932002-08-15Marcus Comstedt  Pike_fatal("o_cast left stack droppings.\n");
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) #endif }
14bb592000-05-06Fredrik Hübinette (Hubbe)  END_CYCLIC();
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  assign_svalue(sp-3,sp-1); pop_stack(); } pop_stack(); } break; case T_MAPPING: {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *itype, *vtype;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  INT32 run_time_itype; INT32 run_time_vtype;
d68a072001-02-20Henrik Grubbström (Grubba)  push_type_value(itype = key_type(type, 0));
babd872001-02-23Henrik Grubbström (Grubba)  run_time_itype = compile_type_to_runtime_type(itype);
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba)  push_type_value(vtype = index_type(type, mixed_type_string, 0));
babd872001-02-23Henrik Grubbström (Grubba)  run_time_vtype = compile_type_to_runtime_type(vtype);
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  if(run_time_itype != T_MIXED || run_time_vtype != T_MIXED) { struct mapping *m; struct mapping *tmp=sp[-3].u.mapping; DECLARE_CYCLIC(); if((m=(struct mapping *)BEGIN_CYCLIC(tmp,0))) { ref_push_mapping(m); }else{
a5cd6a2001-09-24Henrik Grubbström (Grubba)  INT32 e;
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  struct keypair *k; #ifdef PIKE_DEBUG struct svalue *save_sp=sp+1; #endif
06f6112000-01-27Fredrik Hübinette (Hubbe)  push_mapping(m=allocate_mapping(m_sizeof(tmp)));
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  SET_CYCLIC_RET(m); MAPPING_LOOP(tmp) { push_svalue(& k->ind); o_cast(itype, run_time_itype); push_svalue(& k->val); o_cast(vtype, run_time_vtype); mapping_insert(m,sp-2,sp-1); pop_n_elems(2); } #ifdef PIKE_DEBUG if(save_sp!=sp)
5aad932002-08-15Marcus Comstedt  Pike_fatal("o_cast left stack droppings.\n");
1a3e1b1999-04-13Fredrik Hübinette (Hubbe) #endif }
14bb592000-05-06Fredrik Hübinette (Hubbe)  END_CYCLIC();
1a3e1b1999-04-13Fredrik Hübinette (Hubbe)  assign_svalue(sp-4,sp-1); pop_stack(); } pop_n_elems(2); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_cast(void)
98f2b11998-02-19Fredrik Hübinette (Hubbe) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
98f2b11998-02-19Fredrik Hübinette (Hubbe)  struct svalue *save_sp=sp;
d68a072001-02-20Henrik Grubbström (Grubba)  if(sp[-2].type != T_TYPE)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Cast expression destroyed stack or left droppings! (Type:%d)\n",
b103b32001-02-20Henrik Grubbström (Grubba)  sp[-2].type);
98f2b11998-02-19Fredrik Hübinette (Hubbe) #endif
d68a072001-02-20Henrik Grubbström (Grubba)  o_cast(sp[-2].u.type,
07f5432001-02-21Henrik Grubbström (Grubba)  compile_type_to_runtime_type(sp[-2].u.type));
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
98f2b11998-02-19Fredrik Hübinette (Hubbe)  if(save_sp != sp)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Internal error: o_cast() left droppings on stack.\n");
98f2b11998-02-19Fredrik Hübinette (Hubbe) #endif free_svalue(sp-2); sp[-2]=sp[-1]; sp--;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
98f2b11998-02-19Fredrik Hübinette (Hubbe) }
d49add2001-04-25Fredrik Hübinette (Hubbe) void o_breakpoint(void) { /* Does nothing */ }