From 68ec3f29a244c8dd4c94d6fde8133d2d5697428c Mon Sep 17 00:00:00 2001
From: Martin Nilsson <nilsson@opera.com>
Date: Mon, 18 Aug 2014 17:38:59 +0200
Subject: [PATCH] Improved cast.

---
 src/builtin.cmod                              |  45 +++----
 src/error.c                                   |  14 +-
 src/errors.h                                  |   2 +-
 src/modules/Gmp/mpf.cmod                      |  62 ++-------
 src/modules/Gmp/mpq.cmod                      |  67 ++-------
 src/modules/Gmp/mpz_glue.c                    |  74 ++--------
 src/modules/Image/colors.c                    |  21 +--
 src/modules/Image/colortable.c                |  44 +++---
 src/modules/Image/encodings/xcf.c             |  19 ++-
 src/modules/Image/image.c                     |  62 ++++-----
 src/modules/Image/layers.c                    | 127 +++++++++---------
 src/modules/Java/jvm.c                        |  10 +-
 src/modules/Java/module.pmod.in               |   4 +-
 src/modules/Math/math_matrix.c                |   1 +
 src/modules/Math/matrix_code.h                |  47 +++----
 src/modules/Oracle/oracle.c                   |  17 ++-
 src/modules/_Stdio/stat.c                     |  47 +++----
 src/modules/_WhiteFish/resultset.c            |  18 ++-
 src/modules/system/memory.c                   |  54 ++++----
 src/pike_types.c                              |  38 ++++++
 src/pike_types.h                              |  13 ++
 src/post_modules/COM/com.c                    |  17 ++-
 src/post_modules/CritBit/tree_source.H        |  22 ++-
 src/post_modules/GTK2/source/gdkevent.pre     |   7 +-
 src/post_modules/GTK2/source/gdkrectangle.pre |  15 ++-
 src/post_modules/SDL/SDL.cmod                 |  19 +--
 src/post_modules/_ADT/circular_list.cmod      |  12 +-
 src/post_modules/_ADT/sequence.cmod           |  17 +--
 src/post_modules/_ADT/testsuite.in            |  12 +-
 src/post_modules/_Regexp_PCRE/module.pmod.in  |   6 +-
 30 files changed, 394 insertions(+), 519 deletions(-)

diff --git a/src/builtin.cmod b/src/builtin.cmod
index a4bba5b56b..680f7407b8 100644
--- a/src/builtin.cmod
+++ b/src/builtin.cmod
@@ -452,21 +452,20 @@ PIKECLASS TM
     }
 
     PIKEFUN mixed cast( string to )
+      flags ID_PROTECTED;
     {
-        struct pike_string *s_string, *s_int;
-        MAKE_CONST_STRING(s_int, "int");
-        MAKE_CONST_STRING(s_string, "string");
-        if( to == s_int )
+        if( to == literal_int_string )
         {
             f_TM_unix_time(0);
             return;
         }
-        if( to == s_string )
+        if( to == literal_string_string )
         {
             f_TM_asctime(0);
             return;
-       }
-       Pike_error("Does not know how to cast to %s\n", to->str );
+        }
+        pop_stack();
+        push_undefined();
     }
 
     /*! @decl string zone
@@ -3074,15 +3073,11 @@ PIKECLASS Buffer
    *! a @expr{string@} and an @expr{int@}.
    */
   PIKEFUN mixed cast( string type )
+    flags ID_PROTECTED;
   {
-    struct pike_string *string_t;
-    struct pike_string *int_t;
-    MAKE_CONST_STRING( string_t, "string" );
-    MAKE_CONST_STRING( int_t, "int" );
-
-    if( type == string_t )
+    if( type == literal_string_string )
     {
-      pop_n_elems( args );
+      pop_stack();
       if( Pike_fp->current_object->refs != 1 )
 	f_Buffer_get_copy( 0 );
       else
@@ -3090,7 +3085,7 @@ PIKECLASS Buffer
       return;
     }
 
-    if( type == int_t )
+    if( type == literal_int_string )
     {
       struct Buffer_struct *str = THIS;
       pop_stack();
@@ -3101,7 +3096,9 @@ PIKECLASS Buffer
       o_cast_to_int( );
       return;
     }
-    Pike_error("Cannot cast to %S\n", type);
+
+    pop_stack();
+    push_undefined();
   }
   
   /*! @decl String.Buffer `+( string|String.Buffer what )
@@ -5493,15 +5490,13 @@ PIKECLASS List
   PIKEFUN mixed cast(string type)
     flags ID_PROTECTED;
   {
-      if (type == MK_STRING("array")) {
-	pop_n_elems(args);
-	apply_current(f_List_cq__values_fun_num, 0);
-      } else if (type == MK_STRING("object")) {
-	pop_n_elems(args);
-	ref_push_object(Pike_fp->current_object);
-      } else {
-	Pike_error("Cannot cast to %o.\n", Pike_sp-1);
-      }
+    pop_stack(); /* type as at least one more reference. */
+    if (type == literal_array_string)
+      apply_current(f_List_cq__values_fun_num, 0);
+    else if (type == literal_object_string)
+      ref_push_object(Pike_fp->current_object);
+    else
+      push_undefined();
   }
 
 
diff --git a/src/error.c b/src/error.c
index 6bd8a39043..7828ed8ff4 100644
--- a/src/error.c
+++ b/src/error.c
@@ -22,6 +22,7 @@
 #include "module_support.h"
 #include "threads.h"
 #include "gc.h"
+#include "pike_types.h"
 
 /* __attribute__ only applies to function declarations, not
    definitions, so we disable them here. */
@@ -624,16 +625,17 @@ PMOD_EXPORT DECLSPEC(noreturn) void debug_fatal(const char *fmt, ...) ATTRIBUTE(
  */
 static void f_error_cast(INT32 args)
 {
-  char *s;
-  get_all_args("error->cast",args,"%s",&s);
-  if(!strncmp(s,"array",5))
+  if(Pike_sp[-1].u.string == literal_array_string)
   {
-    pop_n_elems(args);
+    pop_stack();
     apply_current (generic_err_message_fun, 0);
     apply_current (generic_err_backtrace_fun, 0);
     f_aggregate(2);
-  }else{
-    SIMPLE_BAD_ARG_ERROR("error->cast", 1, "the value \"array\"");
+  }
+  else
+  {
+    pop_stack();
+    push_undefined();
   }
 }
 
diff --git a/src/errors.h b/src/errors.h
index d0d9d659b7..ba1dae6fef 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -112,7 +112,7 @@
 DECLARE_ERROR(generic, Generic, EMPTY ,
   ERR_VAR(struct pike_string *,tStr,PIKE_T_STRING,error_message)
   ERR_VAR(struct array *,tArray,PIKE_T_ARRAY,error_backtrace)
-  ERR_FUNC("cast",f_error_cast,tFunc(tString,tArray),ID_PROTECTED)
+  ERR_FUNC("cast",f_error_cast,tFunc(tString,tArray),ID_PRIVATE)
   ERR_FUNC("`[]",f_error_index,tFunc(tInt01,tMixed),ID_PROTECTED)
   ERR_FUNC("_sizeof",f_error__sizeof,tFunc(tNone,tInt2),ID_PROTECTED)
   ERR_FUNC("_indices",f_error__indices,tFunc(tNone,tArr(tInt01)),ID_PROTECTED)
diff --git a/src/modules/Gmp/mpf.cmod b/src/modules/Gmp/mpf.cmod
index 678d89f323..5e813020f6 100644
--- a/src/modules/Gmp/mpf.cmod
+++ b/src/modules/Gmp/mpf.cmod
@@ -354,59 +354,15 @@ PIKECLASS mpf
   PIKEFUN mixed cast(string s)
     flags ID_PROTECTED;
   {
-    add_ref(s);
-      
-    pop_n_elems(args);
-      
-    if (s->len) {
-      switch(s->str[0])
-      {
-	case 's':
-	  if(!strcmp(s->str, "string"))
-	  {
-	    free_string(s);
-	    f_mpf_get_string(0);
-	    return;
-	  }
-	  break;
-
-	case 'i':
-	  if(!strncmp(s->str, "int", 3))
-	  {
-	    free_string(s);
-	    f_mpf_get_int(0);
-	    return;
-	  }
-	  break;
-
-	case 'f':
-	  if(!strcmp(s->str, "float"))
-	  {
-	    free_string(s);
-	    f_mpf_get_float(0);
-	    return;
-	  }
-	  break;
-	  
-	case 'o':
-	  if(!strcmp(s->str, "object"))
-	  {
-	    push_object(this_object());
-	  }
-	  break;
-	  
-	case 'm':
-	  if(!strcmp(s->str, "mixed"))
-	  {
-	    push_object(this_object());
-	  }
-	  break;	  
-      }
-    }  
-    push_string(s);	/* Free it when the stack unwinds. */
-      
-    Pike_error("Gmp.mpf cast to \"%S\" is other type than int, string or float.\n",
-	       s);
+    pop_stack(); /* s have at least one more reference. */
+    if( s == literal_string_string )
+      f_mpf_get_string(0);
+    else if( s == literal_int_string )
+      f_mpf_get_int(0);
+    else if( s == literal_float_string )
+      f_mpf_get_float(0);
+    else
+      push_undefined();
   }
 
 #ifdef DEBUG_MALLOC
diff --git a/src/modules/Gmp/mpq.cmod b/src/modules/Gmp/mpq.cmod
index f31f0a4f80..835b30c76a 100644
--- a/src/modules/Gmp/mpq.cmod
+++ b/src/modules/Gmp/mpq.cmod
@@ -35,6 +35,7 @@
 #include "operators.h"
 #include "mapping.h"
 #include "gc.h"
+#include "pike_types.h"
 
 #include <limits.h>
 #include <math.h>
@@ -629,61 +630,17 @@ PIKECLASS mpq
    */
   PIKEFUN int|string|float|object cast(string s)
     flags ID_PROTECTED;
-    {
-      add_ref(s);
-      
-      pop_n_elems(args);
-      
-      switch(s->str[0])
-      {
-	case 'i':
-	  if(!strncmp(s->str, "int", 3))
-	  {
-	    free_string(s);
-	    f_mpq_get_int(0);
-	    return;
-	  }
-	  break;
-	  
-	case 's':
-	  if(!strcmp(s->str, "string"))
-	  {
-	    free_string(s);
-	    format_string (THISMPQ, 1);
-	    return;
-	  }
-	  break;
-
-	case 'f':
-	  if(!strcmp(s->str, "float"))
-	  {
-	    free_string(s);
-	    f_mpq_get_float(0);
-	    return;
-	  }
-	  break;
-	  
-	case 'o':
-	  if(!strcmp(s->str, "object"))
-	  {
-	    push_object(this_object());
-	  }
-	  break;
-	  
-	case 'm':
-	  if(!strcmp(s->str, "mixed"))
-	  {
-	    push_object(this_object());
-	  }
-	  break;
-	  
-      }
-      
-      free_string(s);
-
-      SIMPLE_ARG_ERROR ("Gmp.mpq->cast", 1,
-			"Cannot cast to other type than sitrng, int or float.\n");
-    }
+  {
+    pop_stack(); /* s have at least one more reference. */
+    if( s == literal_int_string )
+      f_mpq_get_int(0);
+    else if( s == literal_string_string )
+      format_string (THISMPQ, 1);
+    else if( s == literal_float_string )
+      f_mpq_get_float(0);
+    else
+      push_undefined();
+  }
 
   /*! @decl static Gmp.mpq `+(int|float|object ... a)
    */
diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c
index e65bb50c55..9f54f1c42b 100644
--- a/src/modules/Gmp/mpz_glue.c
+++ b/src/modules/Gmp/mpz_glue.c
@@ -1080,67 +1080,17 @@ static void mpzmod_size(INT32 args)
  */
 static void mpzmod_cast(INT32 args)
 {
-  struct pike_string *s;
-
-  if(args < 1)
-    SIMPLE_TOO_FEW_ARGS_ERROR("Gmp.mpz->cast", 1);
-  if(TYPEOF(sp[-args]) != T_STRING)
-    SIMPLE_ARG_TYPE_ERROR ("Gmp.mpz->cast", 1, "string");
-
-  s = sp[-args].u.string;
-  add_ref(s);
-
-  pop_n_elems(args);
-
-  switch(s->str[0])
-  {
-  case 'i':
-    if(!strncmp(s->str, "int", 3))
-    {
-      free_string(s);
-      mpzmod_get_int(0);
-      return;
-    }
-    break;
-
-  case 's':
-    if(!strcmp(s->str, "string"))
-    {
-      free_string(s);
-      mpzmod_get_string(0);
-      return;
-    }
-    break;
-
-  case 'f':
-    if(!strcmp(s->str, "float"))
-    {
-      free_string(s);
-      mpzmod_get_float(0);
-      return;
-    }
-    break;
-
-  case 'o':
-    if(!strcmp(s->str, "object"))
-    {
-      push_object(this_object());
-    }
-    break;
-
-  case 'm':
-    if(!strcmp(s->str, "mixed"))
-    {
-      push_object(this_object());
-    }
-    break;
-    
-  }
-
-  push_string(s);	/* To get it freed when Pike_error() pops the stack. */
-
-  SIMPLE_ARG_ERROR ("Gmp.mpz->cast", 1,
-		    "Cannot cast to other type than int, string or float.");
+  struct pike_string *s = sp[-args].u.string;
+  pop_stack(); /* s have at least one more reference. */
+
+  if( s == literal_int_string )
+    mpzmod_get_int(0);
+  else if( s == literal_string_string )
+    mpzmod_get_string(0);
+  else if( s == literal_float_string )
+    mpzmod_get_float(0);
+  else
+    push_undefined();
 }
 
 /* Non-reentrant */
@@ -2365,7 +2315,7 @@ static void pike_mp_free (void *ptr, size_t UNUSED(size))
   ADD_FUNCTION("`!",mpzmod_not,tFunc(tNone,tInt01), ID_PROTECTED);	\
 									\
   ADD_FUNCTION("__hash",mpzmod___hash,tFunc(tNone,tInt), ID_PROTECTED);	\
-  ADD_FUNCTION("cast",mpzmod_cast,tFunc(tStr,tMix), ID_PROTECTED);	\
+  ADD_FUNCTION("cast",mpzmod_cast,tFunc(tStr,tMix), ID_PRIVATE);	\
 									\
   ADD_FUNCTION("_is_type", mpzmod__is_type, tFunc(tStr,tInt01),         \
                ID_PROTECTED);                                           \
diff --git a/src/modules/Image/colors.c b/src/modules/Image/colors.c
index 3cf40344fb..90b7638766 100644
--- a/src/modules/Image/colors.c
+++ b/src/modules/Image/colors.c
@@ -209,6 +209,7 @@
 #include "module_support.h"
 #include "sscanf.h"
 #include "program_id.h"
+#include "pike_types.h"
 
 #include "image.h"
 #include "colortable.h"
@@ -223,9 +224,6 @@ static struct array *colornames=NULL;
 struct program *image_color_program=NULL;
 extern struct program *image_colortable_program;
 
-static struct pike_string *str_array;
-static struct pike_string *str_string;
-static struct pike_string *str_int;
 static struct pike_string *str_r;
 static struct pike_string *str_g;
 static struct pike_string *str_b;
@@ -763,23 +761,24 @@ static void image_color_cast(INT32 args)
       bad_arg_error("Image.Color.Color->cast",sp-args,args,0,"",sp-args,
 		"Bad arguments to Image.Color.Color->cast()\n");
    
-   if (sp[-1].u.string==str_array)
+   if (sp[-1].u.string==literal_array_string)
    {
       image_color_rgb(args);
       return;
    }
-   if (sp[-1].u.string==str_string)
+   if (sp[-1].u.string==literal_string_string)
    {
       image_color_name(args);
       return;
    }
-   if (sp[-1].u.string==str_int)
+   if (sp[-1].u.string==literal_int_string)
    {
      pop_stack();
      push_int( (THIS->rgb.r << 8 | THIS->rgb.g)  << 8 | THIS->rgb.b );
      return;
    }
-   Pike_error("Image.Color.Color->cast(): Can't cast to that\n");
+   pop_stack();
+   push_undefined();
 }
 
 static void image_color__sprintf(INT32 args)
@@ -1721,9 +1720,6 @@ static void image_colors_values(INT32 args)
 
 void init_image_colors(void)
 {
-   str_array=make_shared_string("array");
-   str_string=make_shared_string("string");
-   str_int=make_shared_string("int");
    str_r=make_shared_string("r");
    str_g=make_shared_string("g");
    str_b=make_shared_string("b");
@@ -1743,7 +1739,7 @@ void init_image_colors(void)
 
    /* color info methods */
 
-   ADD_FUNCTION("cast",image_color_cast,tFunc(tStr,tOr(tArray,tStr)),0);
+   ADD_FUNCTION("cast",image_color_cast,tFunc(tStr,tOr(tArray,tStr)),ID_PROTECTED);
    ADD_FUNCTION("_sprintf",image_color__sprintf,
 		tFunc(tInt tMap(tStr,tMix),tStr),0);
    ADD_FUNCTION("`[]",image_color_index,tFunc(tOr(tStr,tInt),tOr(tInt,tFunction)),0);
@@ -1843,9 +1839,6 @@ void exit_image_colors(void)
       for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++)
 	 free_string(html_color[i].pname);
    }
-   free_string(str_array);
-   free_string(str_string);
-   free_string(str_int);
    free_string(str_r);
    free_string(str_g);
    free_string(str_b);
diff --git a/src/modules/Image/colortable.c b/src/modules/Image/colortable.c
index 52a432eb2f..8b26d649fa 100644
--- a/src/modules/Image/colortable.c
+++ b/src/modules/Image/colortable.c
@@ -39,6 +39,7 @@
 #include "operators.h"
 #include "dmalloc.h"
 #include "bignum.h"
+#include "pike_types.h"
 
 #include "image.h"
 #include "colortable.h"
@@ -2736,31 +2737,22 @@ static void image_colortable__decode( INT32 args )
 
 void image_colortable_cast(INT32 args)
 {
-   if (!args)
-      SIMPLE_TOO_FEW_ARGS_ERROR("Image.Colortable->cast",1);
-   if (TYPEOF(sp[-args]) == T_STRING || sp[-args].u.string->size_shift)
-   {
-      if (!strncmp(sp[-args].u.string->str,"array",5))
-      {
-	 pop_n_elems(args);
-	 image_colortable_cast_to_array(THIS);
-	 return;
-      }
-      if (!strncmp(sp[-args].u.string->str,"string",6))
-      {
-	 pop_n_elems(args);
-	 image_colortable_cast_to_string(THIS);
-	 return;
-      }
-      if (!strncmp(sp[-args].u.string->str,"mapping",7))
-      {
-	 pop_n_elems(args);
-	 image_colortable_cast_to_mapping(THIS);
-	 return;
-      }
-   }
-   SIMPLE_BAD_ARG_ERROR("Image.Colortable->cast",1,
-			"string(\"mapping\"|\"array\"|\"string\")");
+  struct pike_string *type;
+
+  if (!args)
+    SIMPLE_TOO_FEW_ARGS_ERROR("Image.Colortable->cast",1);
+
+  type = Pike_sp[-args].u.string;
+  pop_n_elems(args); /* type have at least one more reference. */
+
+  if (type == literal_array_string)
+    image_colortable_cast_to_array(THIS);
+  else if (type == literal_string_string)
+    image_colortable_cast_to_string(THIS);
+  else if (type == literal_mapping_string)
+    image_colortable_cast_to_mapping(THIS);
+  else
+    push_undefined();
 }
 
 /*
@@ -4516,7 +4508,7 @@ void init_image_colortable(void)
    ADD_FUNCTION("``+",image_colortable_operator_plus,tFunc(tObj,tObj),0);
 
    /* cast to array */
-   ADD_FUNCTION("cast",image_colortable_cast,tFunc(tStr,tArray),0);
+   ADD_FUNCTION("cast",image_colortable_cast,tFunc(tStr,tArray),ID_PROTECTED);
 
    /* info */
    ADD_FUNCTION("_sizeof",image_colortable__sizeof,tFunc(tNone,tInt),0);
diff --git a/src/modules/Image/encodings/xcf.c b/src/modules/Image/encodings/xcf.c
index 10817ecaa2..5f5af2b4b1 100644
--- a/src/modules/Image/encodings/xcf.c
+++ b/src/modules/Image/encodings/xcf.c
@@ -21,6 +21,7 @@
 #include "stralloc.h"
 #include "builtin_functions.h"
 #include "bignum.h"
+#include "pike_types.h"
 
 #include "image.h"
 #include "colortable.h"
@@ -65,11 +66,17 @@ static struct program *substring_program;
 
 static void f_substring_cast( INT32 args )
 {
-  /* FIXME: assumes string */
-  struct substring *s = SS(fp->current_object);
-  pop_n_elems( args );
-  push_string( make_shared_binary_string( (((char *)s->s->str)+s->offset),
-                                          s->len ) );
+  struct pike_string *type = sp[-args].u.string;
+  pop_n_elems(args); /* type have at least one more reference. */
+
+  if( type == literal_string_string )
+  {
+    struct substring *s = SS(fp->current_object);
+    push_string( make_shared_binary_string( (((char *)s->s->str)+s->offset),
+                                            s->len ) );
+  }
+  else
+    push_undefined();
 }
 
 static void f_substring_index( INT32 args )
@@ -1489,7 +1496,7 @@ void init_image_xcf()
 
   start_new_program();
   ADD_STORAGE( struct substring );
-  ADD_FUNCTION("cast", f_substring_cast, tFunc(tStr,tMix), 0);
+  ADD_FUNCTION("cast", f_substring_cast, tFunc(tStr,tMix), ID_PRIVATE);
   ADD_FUNCTION("`[]", f_substring_index, tFunc(tInt,tInt), 0);
   ADD_FUNCTION("get_short", f_substring_get_short, tFunc(tInt,tInt), 0 );
   ADD_FUNCTION("get_ushort", f_substring_get_ushort, tFunc(tInt,tInt), 0 );
diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c
index decb16d6c9..967846681d 100644
--- a/src/modules/Image/image.c
+++ b/src/modules/Image/image.c
@@ -110,7 +110,7 @@
 #include "array.h"
 #include "pike_error.h"
 #include "module_support.h"
-
+#include "pike_types.h"
 
 #include "image.h"
 #include "colortable.h"
@@ -4511,44 +4511,40 @@ void image_read_lsb_grey(INT32 args)
 
 void image_cast(INT32 args)
 {
-   if (!args)
-      SIMPLE_TOO_FEW_ARGS_ERROR("Image.Image->cast",1);
-   if (TYPEOF(sp[-args]) == T_STRING || sp[-args].u.string->size_shift)
-   {
-     if (!THIS->img)
-       Pike_error("Called Image.Image object is not initialized\n");
+  struct pike_string *type;
 
-      if (strncmp(sp[-args].u.string->str,"array",5)==0)
-      {
-	 int i,j;
-	 rgb_group *s=THIS->img;
+  if (!args)
+    SIMPLE_TOO_FEW_ARGS_ERROR("Image.Image->cast",1);
+  if (!THIS->img)
+    Pike_error("Called Image.Image object is not initialized\n");
 
-	 pop_n_elems(args);
+  type = sp[-args].u.string;
+  pop_n_elems(args); /* type have at least one more reference. */
 
-	 for (i=0; i<THIS->ysize; i++)
-	 {
-	    for (j=0; j<THIS->xsize; j++)
-	    {
-	       _image_make_rgb_color(s->r,s->g,s->b);
-	       s++;
-	    }
-	    f_aggregate(THIS->xsize);
-	 }
-	 f_aggregate(THIS->ysize);
+  if (type == literal_array_string)
+  {
+    int i,j;
+    rgb_group *s=THIS->img;
 
-	 return;
-      }
-      if (strncmp(sp[-args].u.string->str,"string",6)==0)
+    for (i=0; i<THIS->ysize; i++)
+    {
+      for (j=0; j<THIS->xsize; j++)
       {
-	 pop_n_elems(args);
-	 push_string(make_shared_binary_string((char *)THIS->img,
-					       THIS->xsize*THIS->ysize
-					       *sizeof(rgb_group)));
-	 return;
+        _image_make_rgb_color(s->r,s->g,s->b);
+        s++;
       }
-      
+      f_aggregate(THIS->xsize);
+    }
+    f_aggregate(THIS->ysize);
    }
-   SIMPLE_BAD_ARG_ERROR("Image.Image->cast",1,"string(\"array\"|\"string\")");
+   else if (type == literal_string_string)
+   {
+     push_string(make_shared_binary_string((char *)THIS->img,
+                                           THIS->xsize*THIS->ysize
+                                           *sizeof(rgb_group)));
+   }
+   else
+     push_undefined();
 }
 
 static void image__sprintf( INT32 args )
@@ -4905,7 +4901,7 @@ void init_image_image(void)
 		tFunc(tRGB,tObj),0);
 
    ADD_FUNCTION("cast",image_cast,
-		tFunc(tStr,tStr),0);
+		tFunc(tStr,tStr),ID_PROTECTED);
    ADD_FUNCTION("tobitmap",image_tobitmap,tFunc(tNone,tStr),0);
 
 
diff --git a/src/modules/Image/layers.c b/src/modules/Image/layers.c
index 0b42f2725c..03c9209095 100644
--- a/src/modules/Image/layers.c
+++ b/src/modules/Image/layers.c
@@ -28,6 +28,7 @@
 #include "dmalloc.h"
 #include "operators.h"
 #include "module_support.h"
+#include "pike_types.h"
 
 #include "image.h"
 
@@ -1424,76 +1425,72 @@ static void image_layer_create(INT32 args)
  */
 static void image_layer_cast(INT32 args)
 {
-   if (!args)
-      SIMPLE_TOO_FEW_ARGS_ERROR("Image.Layer->cast",1);
-   if (TYPEOF(Pike_sp[-args]) == T_STRING ||
-       Pike_sp[-args].u.string->size_shift)
-   {
-      if (strncmp(Pike_sp[-args].u.string->str,"mapping",7)==0)
-      {
-	 int n=0;
-	 pop_n_elems(args);
+  struct pike_string *type;
 
-	 push_text("xsize");       push_int(THIS->xsize);         n++;
-	 push_text("ysize");       push_int(THIS->ysize);         n++;
-	 push_text("image");       image_layer_image(0);          n++;
-	 push_text("alpha");       image_layer_alpha(0);          n++;
-	 push_text("xoffset");     push_int(THIS->xoffs);         n++;
-	 push_text("yoffset");     push_int(THIS->yoffs);         n++;
-	 push_text("alpha_value"); push_float(THIS->alpha_value); n++;
-	 push_text("fill");        image_layer_fill(0);           n++;
-	 push_text("fill_alpha");  image_layer_fill_alpha(0);     n++;
-	 push_text("tiled");       push_int(THIS->tiled);         n++;
-	 push_text("mode");        image_layer_mode(0);           n++;
+  if (!args)
+    SIMPLE_TOO_FEW_ARGS_ERROR("Image.Layer->cast",1);
 
-	 f_aggregate_mapping(n*2);
+  type = Pike_sp[-args].u.string;
+  pop_n_elems(args); /* type have at least one more reference. */
 
-	 return;
+  if (type == literal_mapping_string)
+  {
+    int n=0;
+
+    push_text("xsize");       push_int(THIS->xsize);         n++;
+    push_text("ysize");       push_int(THIS->ysize);         n++;
+    push_text("image");       image_layer_image(0);          n++;
+    push_text("alpha");       image_layer_alpha(0);          n++;
+    push_text("xoffset");     push_int(THIS->xoffs);         n++;
+    push_text("yoffset");     push_int(THIS->yoffs);         n++;
+    push_text("alpha_value"); push_float(THIS->alpha_value); n++;
+    push_text("fill");        image_layer_fill(0);           n++;
+    push_text("fill_alpha");  image_layer_fill_alpha(0);     n++;
+    push_text("tiled");       push_int(THIS->tiled);         n++;
+    push_text("mode");        image_layer_mode(0);           n++;
+
+    f_aggregate_mapping(n*2);
+  }
+  else if (type == literal_string_string)
+  {
+    size_t size = THIS->xsize*THIS->ysize, i;
+    struct pike_string *s = begin_shared_string(size*4);
+    rgb_group *img = 0;
+    rgb_group *alp = 0;
+
+    if(THIS->img)
+      img = THIS->img->img;
+    if(THIS->alp)
+      alp = THIS->alp->img;
+
+    if(img && alp)
+      for(i=0; i<size; i++) {
+        s->str[i*4+0] = img[i].r;
+        s->str[i*4+1] = img[i].g;
+        s->str[i*4+2] = img[i].b;
+        s->str[i*4+3] = alp[i].r;
       }
-      else if (strncmp(Pike_sp[-args].u.string->str,"string",6)==0)
-      {
-	size_t size = THIS->xsize*THIS->ysize, i;
-	struct pike_string *s = begin_shared_string(size*4);
-	rgb_group *img = 0;
-	rgb_group *alp = 0;
-
-	pop_n_elems(args);
-	if(THIS->img)
-	  img = THIS->img->img;
-	if(THIS->alp)
-	  alp = THIS->alp->img;
-
-	if(img && alp)
-	  for(i=0; i<size; i++) {
-	    s->str[i*4+0] = img[i].r;
-	    s->str[i*4+1] = img[i].g;
-	    s->str[i*4+2] = img[i].b;
-	    s->str[i*4+3] = alp[i].r;
-	  }
-	else if(img)
-	  for(i=0; i<size; i++) {
-	    s->str[i*4+0] = img[i].r;
-	    s->str[i*4+1] = img[i].g;
-	    s->str[i*4+2] = img[i].b;
-	    s->str[i*4+3] = 255;
-	  }
-	else if(alp)
-	  for(i=0; i<size; i++) {
-	    s->str[i*4+0] = 255;
-	    s->str[i*4+1] = 255;
-	    s->str[i*4+2] = 255;
-	    s->str[i*4+3] = alp[i].r;
-	  }
-	else
-	  memset(s->str, 0, size*4);
-
-	push_string(end_shared_string(s));
-	return;
+    else if(img)
+      for(i=0; i<size; i++) {
+        s->str[i*4+0] = img[i].r;
+        s->str[i*4+1] = img[i].g;
+        s->str[i*4+2] = img[i].b;
+        s->str[i*4+3] = 255;
       }
-   }
-   SIMPLE_BAD_ARG_ERROR("Image.Colortable->cast",1,
-			"string(\"mapping\"|\"string\")");
+    else if(alp)
+      for(i=0; i<size; i++) {
+        s->str[i*4+0] = 255;
+        s->str[i*4+1] = 255;
+        s->str[i*4+2] = 255;
+        s->str[i*4+3] = alp[i].r;
+      }
+    else
+      memset(s->str, 0, size*4);
 
+    push_string(end_shared_string(s));
+  }
+  else
+    push_undefined();
 }
 
 /*** layer mode definitions ***************************/
@@ -3302,7 +3299,7 @@ void init_image_layers(void)
    ADD_FUNCTION("_sprintf",image_layer__sprintf,
                 tFunc(tInt tMapping,tString),0);
    ADD_FUNCTION("cast",image_layer_cast,
-		tFunc(tString,tMapping),0);
+		tFunc(tString,tMapping),ID_PROTECTED);
 
 
    ADD_FUNCTION("clone",image_layer_clone,
diff --git a/src/modules/Java/jvm.c b/src/modules/Java/jvm.c
index 80a39de5b5..5f9f4d3deb 100644
--- a/src/modules/Java/jvm.c
+++ b/src/modules/Java/jvm.c
@@ -33,6 +33,7 @@
 #include "threads.h"
 #include "operators.h"
 #include "signal_handler.h"
+#include "pike_types.h"
 
 #ifdef HAVE_JAVA
 
@@ -386,14 +387,13 @@ static void f_jobj_cast(INT32 args)
   if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING)
     Pike_error("Bad argument 1 to cast().\n");
 
-  if(!strcmp(Pike_sp[-args].u.string->str, "object")) {
+  if(Pike_sp[-args].u.string != literal_string_string)
+  {
     pop_n_elems(args);
-    push_object(this_object());
+    push_undefined();
+    return;
   }
 
-  if(strcmp(Pike_sp[-args].u.string->str, "string"))
-    Pike_error("cast() to other type than string.\n");
-
   pop_n_elems(args);
   if((env=jvm_procure_env(jo->jvm))) {
     jstr = (*env)->CallObjectMethod(env, jo->jobj, j->method_tostring);
diff --git a/src/modules/Java/module.pmod.in b/src/modules/Java/module.pmod.in
index d39217f2ee..c52c677f28 100644
--- a/src/modules/Java/module.pmod.in
+++ b/src/modules/Java/module.pmod.in
@@ -291,7 +291,7 @@ protected class jobject {
     return cls->_wrap_result(x);
   }
 
-  protected mixed cast(mixed ... args)
+  mixed cast(mixed ... args)
   {
     return obj->cast(@unwrap_args(args));
   }
@@ -358,7 +358,7 @@ protected class jarray {
   protected object obj;
   mapping(string:mixed) info;
 
-  protected mixed cast(mixed ... args)
+  mixed cast(mixed ... args)
   {
     return obj->cast(@unwrap_args(args));
   }
diff --git a/src/modules/Math/math_matrix.c b/src/modules/Math/math_matrix.c
index 9052d7a366..9821300a7e 100644
--- a/src/modules/Math/math_matrix.c
+++ b/src/modules/Math/math_matrix.c
@@ -16,6 +16,7 @@
 #include "builtin_functions.h"
 #include "module_support.h"
 #include "operators.h"
+#include "pike_types.h"
 
 #include "math_module.h"
 
diff --git a/src/modules/Math/matrix_code.h b/src/modules/Math/matrix_code.h
index 33efb9d66f..ebde77ac83 100644
--- a/src/modules/Math/matrix_code.h
+++ b/src/modules/Math/matrix_code.h
@@ -284,29 +284,30 @@ void matrixX(_cast)(INT32 args)
       push_int(0);
    }
 
-   if (args)
-      if (TYPEOF(Pike_sp[-1]) == T_STRING) {
-	 if (Pike_sp[-1].u.string==s_array)
-	 {
-	    int i,j;
-	    int xs=THIS->xsize,ys=THIS->ysize;
-	    FTYPE *m=THIS->m;
-	    check_stack(DO_NOT_WARN((long)(xs+ys)));
-	    pop_n_elems(args);
-	    for (i=0; i<ys; i++)
-	    {
-	      for (j=0; j<xs; j++)
-		PUSH_ELEM(*(m++));
-	      f_aggregate(xs);
-	    }
-	    f_aggregate(ys);
-	    return;
-	 }
-         else
-           Pike_error("Can only cast to array.\n");
-      }
+   if( !args || TYPEOF(Pike_sp[-1]) != T_STRING )
+     SIMPLE_BAD_ARG_ERROR("cast",1,"string");
 
-   SIMPLE_BAD_ARG_ERROR("cast",1,"string");
+   if( Pike_sp[-1].u.string != literal_array_string )
+   {
+     pop_n_elems(args);
+     push_undefined();
+     return;
+   }
+
+   {
+     int i,j;
+     int xs=THIS->xsize,ys=THIS->ysize;
+     FTYPE *m=THIS->m;
+     check_stack(DO_NOT_WARN((long)(xs+ys)));
+     pop_n_elems(args);
+     for (i=0; i<ys; i++)
+     {
+       for (j=0; j<xs; j++)
+         PUSH_ELEM(*(m++));
+       f_aggregate(xs);
+     }
+     f_aggregate(ys);
+   }
 }
 
 
@@ -977,7 +978,7 @@ void Xmatrix(init_math_)(void)
 		      tFunc(tInt1Plus tInt1Plus tOr4(tInt,tFloat,tString,tVoid), tVoid)), ID_PROTECTED);
 
    ADD_FUNCTION("cast",matrixX(_cast),
-		tFunc(tStr, tArr(tArr(tFloat))), 0);
+		tFunc(tStr, tArr(tArr(tFloat))), ID_PROTECTED);
    ADD_FUNCTION("vect",matrixX(_vect), tFunc(tNone,tArr(PTYPE)), 0);
    ADD_FUNCTION("_sprintf",matrixX(__sprintf), tFunc(tInt tMapping, tStr), 0);
 
diff --git a/src/modules/Oracle/oracle.c b/src/modules/Oracle/oracle.c
index 8b97192fbc..60a7edae73 100644
--- a/src/modules/Oracle/oracle.c
+++ b/src/modules/Oracle/oracle.c
@@ -2538,9 +2538,10 @@ static void dbdate_sprintf(INT32 args)
 
 static void dbdate_cast(INT32 args)
 {
-  char *s;
-  get_all_args("Oracle.Date->cast",args,"%s",&s);
-  if(!strcmp(s,"int"))
+  struct pike_string *type = Pike_sp[-args].u.string;
+  pop_stack(); /* type have at least one more reference. */
+
+  if(type == literal_int_string)
   {
     ub1 hour, min, sec, month,day;
     sb2 year;
@@ -2557,16 +2558,14 @@ static void dbdate_cast(INT32 args)
     push_int(month);
     push_int(year);
     f_mktime(6);
-    return;
   }
-  if(!strcmp(s,"string"))
+  else if(type == literal_string_string)
   {
-    pop_n_elems(args);
     push_int('s');
     dbdate_sprintf(1);
-    return;
   }
-  Pike_error("Cannot cast Oracle.Date to %s\n",s);
+  else
+    push_undefined();
 }
 
 /*
@@ -2753,7 +2752,7 @@ PIKE_MODULE_INIT
 
   MY_START_CLASS(dbdate); {
     ADD_FUNCTION("create",dbdate_create,tFunc(tOr(tStr,tInt),tVoid),0);
-    ADD_FUNCTION("cast",dbdate_cast,tFunc(tStr, tMix),0);
+    ADD_FUNCTION("cast",dbdate_cast,tFunc(tStr, tMix),ID_PRIVATE);
     ADD_FUNCTION("_sprintf",dbdate_sprintf,tFunc(tInt, tStr),0);
   }
   MY_END_CLASS(Date);
diff --git a/src/modules/_Stdio/stat.c b/src/modules/_Stdio/stat.c
index c41ed9aaf5..79b1450141 100644
--- a/src/modules/_Stdio/stat.c
+++ b/src/modules/_Stdio/stat.c
@@ -15,6 +15,7 @@
 #include "operators.h"
 #include "program_id.h"
 #include "file_machine.h"
+#include "pike_types.h"
 
 #include <sys/stat.h>
 #ifdef HAVE_SYS_PARAM_H
@@ -790,32 +791,24 @@ static void stat_values(INT32 args);
 
 static void stat_cast(INT32 args)
 {
-   if (!args)
-      SIMPLE_TOO_FEW_ARGS_ERROR("Stat cast",1);
-   if (TYPEOF(sp[-args]) == T_STRING && !sp[-args].u.string->size_shift)
-   {
-      /* NB: We only look at the prefix, and let the main cast function
-       *     handle any subtypes.
-       */
-      if (!strncmp(sp[-args].u.string->str, "array", 5))
-      {
-	 pop_n_elems(args);
-	 push_int(0);
-	 push_int(6);
-	 stat_index(2);
-	 return;
-      }
-      if (!strncmp(sp[-args].u.string->str, "mapping", 7))
-      {
-        stat_indices(0);
-        stat_values(0);
-        push_mapping(mkmapping(Pike_sp[-2].u.array, Pike_sp[-1].u.array));
-        stack_pop_n_elems_keep_top(2);
-        return;
-      }
-   }
-   SIMPLE_BAD_ARG_ERROR("Stat cast",1,
-			"string(\"array\"|\"mapping\")");
+  struct pike_string *type = Pike_sp[-args].u.string;
+  pop_stack(); /* type have at least one more reference. */
+
+  if (type == literal_array_string)
+  {
+    push_int(0);
+    push_int(6);
+    stat_index(2);
+  }
+  else if (type == literal_mapping_string)
+  {
+    stat_indices(0);
+    stat_values(0);
+    push_mapping(mkmapping(Pike_sp[-2].u.array, Pike_sp[-1].u.array));
+    stack_pop_n_elems_keep_top(2);
+  }
+  else
+    push_undefined();
 }
 
 static void stat__sprintf(INT32 args)
@@ -1036,7 +1029,7 @@ void init_stdio_stat()
 		 tOr(tFunc(tInt06 tSetvar(0,tInt),tVar(0)),
 		     tFunc(tString tSetvar(1,tOr(tInt,tString)),tVar(1))), 0);
 
-   ADD_FUNCTION("cast",stat_cast,tFunc(tStr,tArray),0);
+   ADD_FUNCTION("cast",stat_cast,tFunc(tStr,tArray),ID_PRIVATE);
    ADD_FUNCTION("_sprintf",stat__sprintf,
 		tFunc(tInt tOr(tVoid,tMapping),tString),0);
    ADD_FUNCTION("_indices",stat_indices,
diff --git a/src/modules/_WhiteFish/resultset.c b/src/modules/_WhiteFish/resultset.c
index 52b2015e9d..1ed41c6879 100644
--- a/src/modules/_WhiteFish/resultset.c
+++ b/src/modules/_WhiteFish/resultset.c
@@ -10,6 +10,7 @@
 #include "bignum.h"
 #include "module_support.h"
 #include "fsort.h"
+#include "pike_types.h"
 
 #include "config.h"
 
@@ -220,10 +221,17 @@ static void f_resultset_cast( INT32 args )
  *! data as a array.
  */
 {
-  pop_n_elems( args );
-  push_int(0);
-  push_int( 0x7fffffff );
-  f_resultset_slice(2);
+  struct pike_string *type = Pike_sp[-args].u.string;
+  pop_stack(); /* type have at least one more reference. */
+
+  if( type==literal_array_string )
+  {
+    push_int(0);
+    push_int( 0x7fffffff );
+    f_resultset_slice(2);
+  }
+  else
+    push_undefined();
 }
 
 static void f_resultset_memsize( INT32 args )
@@ -1012,7 +1020,7 @@ void init_resultset_program(void)
   start_new_program();
   {  
     ADD_STORAGE( struct result_set_p );
-    add_function("cast", f_resultset_cast, "function(string:mixed)", 0 );
+    add_function("cast", f_resultset_cast, "function(string:mixed)", ID_PRIVATE );
     add_function("create",f_resultset_create,
 		 "function(void|array(int|array(int)):void)",0);
 
diff --git a/src/modules/system/memory.c b/src/modules/system/memory.c
index 5416ac4a59..26ec45cbb5 100644
--- a/src/modules/system/memory.c
+++ b/src/modules/system/memory.c
@@ -535,39 +535,35 @@ static void memory_writeable(INT32 args)
  */
 static void memory_cast(INT32 args)
 {
-   char *s;
-   get_all_args("Memory.cast",args,"%s",&s);
+  struct pike_string *type = Pike_sp[-args].u.string;
+  pop_stack(); /* type have at least one more reference. */
 
-   MEMORY_VALID(THIS,"Memory.cast");
+  MEMORY_VALID(THIS,"Memory.cast");
    
-   if (strncmp(s,"string",5)==0)
-   {
-      pop_n_elems(args);
-      push_string(make_shared_binary_string((char *)THIS->p, THIS->size));
-      return;
-   }
-   if (strncmp(s,"array",5)==0)
-   {
-      struct array *a;
-      size_t i,sz=THIS->size;
-      struct svalue *sv;
-
-      pop_n_elems(args);
-
-      a=low_allocate_array(sz,0);
+  if (type == literal_string_string)
+  {
+    push_string(make_shared_binary_string((char *)THIS->p, THIS->size));
+  }
+  else if (type == literal_array_string)
+  {
+    struct array *a;
+    size_t i,sz=THIS->size;
+    struct svalue *sv;
 
-      sv=ITEM(a);
-      for (i=0; i<sz; i++)
-      {
-	 sv->u.integer=(((unsigned char*)(THIS->p)))[i];
-	 sv++;
-      }
-      a->type_field = BIT_INT;
+    a=low_allocate_array(sz,0);
 
-      push_array(a);
+    sv=ITEM(a);
+    for (i=0; i<sz; i++)
+    {
+      sv->u.integer=(((unsigned char*)(THIS->p)))[i];
+      sv++;
+    }
+    a->type_field = BIT_INT;
 
-      return;
-   }
+    push_array(a);
+  }
+  else
+    push_undefined();
 }
 
 /*! @decl string pread(int(0..) pos,int(0..) len)
@@ -961,7 +957,7 @@ void init_system_memory(void)
 
    ADD_FUNCTION("_sizeof",memory__sizeof,tFunc(tVoid,tIntPos),0);
    ADD_FUNCTION("cast",memory_cast,
-		tFunc(tStr,tOr(tArr(tInt),tStr)),0);
+		tFunc(tStr,tOr(tArr(tInt),tStr)),ID_PRIVATE);
 
    ADD_FUNCTION("`[]",memory_index,
 		tOr(tFunc(tInt,tInt),
diff --git a/src/pike_types.c b/src/pike_types.c
index b4b7e25f01..12dec6edd4 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -108,6 +108,19 @@ PMOD_EXPORT struct pike_type *weak_type_string;	/* array|mapping|multiset|functi
 struct pike_type *sscanf_type_string;
 struct pike_type *sscanf_76_type_string;
 
+PMOD_EXPORT struct pike_string *literal_string_string;
+PMOD_EXPORT struct pike_string *literal_int_string;
+PMOD_EXPORT struct pike_string *literal_float_string;
+PMOD_EXPORT struct pike_string *literal_function_string;
+PMOD_EXPORT struct pike_string *literal_object_string;
+PMOD_EXPORT struct pike_string *literal_program_string;
+PMOD_EXPORT struct pike_string *literal_array_string;
+PMOD_EXPORT struct pike_string *literal_multiset_string;
+PMOD_EXPORT struct pike_string *literal_mapping_string;
+PMOD_EXPORT struct pike_string *literal_type_string;
+PMOD_EXPORT struct pike_string *literal_mixed_string;
+
+
 #ifdef DO_PIKE_CLEANUP
 struct pike_type_location *all_pike_type_locations = NULL;
 #endif /* DO_PIKE_CLEANUP */
@@ -8769,6 +8782,18 @@ void init_types(void)
 					   tAttr("sscanf_args", tMix), tIntPos));
   /* add_ref(weak_type_string);	*//* LEAK */
 
+  MAKE_CONST_STRING(literal_string_string, "string");
+  MAKE_CONST_STRING(literal_int_string, "int");
+  MAKE_CONST_STRING(literal_float_string, "float");
+  MAKE_CONST_STRING(literal_function_string, "function");
+  MAKE_CONST_STRING(literal_object_string, "object");
+  MAKE_CONST_STRING(literal_program_string, "program");
+  MAKE_CONST_STRING(literal_array_string, "array");
+  MAKE_CONST_STRING(literal_multiset_string, "multiset");
+  MAKE_CONST_STRING(literal_mapping_string, "mapping");
+  MAKE_CONST_STRING(literal_type_string, "type");
+  MAKE_CONST_STRING(literal_mixed_string, "mixed");
+
 #ifdef PIKE_DEBUG
   pike_type_gc_callback = add_gc_callback(gc_mark_external_types, NULL, NULL);
 #endif
@@ -8841,6 +8866,19 @@ void cleanup_pike_types(void)
   sscanf_type_string = NULL;
   free_type(sscanf_76_type_string);
   sscanf_76_type_string = NULL;
+
+  free_string(literal_string_string); literal_string_string = NULL;
+  free_string(literal_int_string); literal_int_string = NULL;
+  free_string(literal_float_string); literal_float_string = NULL;
+  free_string(literal_function_string); literal_function_string = NULL;
+  free_string(literal_object_string); literal_object_string = NULL;
+  free_string(literal_program_string); literal_program_string = NULL;
+  free_string(literal_array_string); literal_array_string = NULL;
+  free_string(literal_multiset_string); literal_multiset_string = NULL;
+  free_string(literal_mapping_string); literal_mapping_string = NULL;
+  free_string(literal_type_string); literal_type_string = NULL;
+  free_string(literal_mixed_string); literal_mixed_string = NULL;
+
 #ifdef PIKE_DEBUG
   remove_callback(pike_type_gc_callback);
 #endif
diff --git a/src/pike_types.h b/src/pike_types.h
index 0f980a76b8..166bec42a5 100644
--- a/src/pike_types.h
+++ b/src/pike_types.h
@@ -141,6 +141,19 @@ PMOD_EXPORT extern struct pike_type *weak_type_string;
 extern struct pike_type *sscanf_type_string;
 extern struct pike_type *sscanf_76_type_string;
 
+PMOD_EXPORT extern struct pike_string *literal_string_string;
+PMOD_EXPORT extern struct pike_string *literal_int_string;
+PMOD_EXPORT extern struct pike_string *literal_float_string;
+PMOD_EXPORT extern struct pike_string *literal_function_string;
+PMOD_EXPORT extern struct pike_string *literal_object_string;
+PMOD_EXPORT extern struct pike_string *literal_program_string;
+PMOD_EXPORT extern struct pike_string *literal_array_string;
+PMOD_EXPORT extern struct pike_string *literal_multiset_string;
+PMOD_EXPORT extern struct pike_string *literal_mapping_string;
+PMOD_EXPORT extern struct pike_string *literal_type_string;
+PMOD_EXPORT extern struct pike_string *literal_mixed_string;
+
+
 #define CONSTTYPE(X) make_pike_type(X)
 
 #ifdef DO_PIKE_CLEANUP
diff --git a/src/post_modules/COM/com.c b/src/post_modules/COM/com.c
index 7419e77d00..fdff33ea74 100644
--- a/src/post_modules/COM/com.c
+++ b/src/post_modules/COM/com.c
@@ -713,17 +713,16 @@ static void f_cval_cast(INT32 args)
   if (TYPEOF(Pike_sp[-args]) != PIKE_T_STRING)
     Pike_error("Bad argument 1 to cast().\n");
 
-  if (!strcmp(Pike_sp[-args].u.string->str, "object")) {
+  if( Pike_sp[-args].u.string == literal_string_string )
+  {
     pop_n_elems(args);
-    push_object(this_object());
+    cval_push_result(0, DISPATCH_PROPERTYGET);
+  }
+  else
+  {
+    pop_n_elems(args);
+    push_undefined();
   }
-
-  
-/*   if (strcmp(Pike_sp[-args].u.string->str, "string")) */
-/*     Pike_error("cast() to other type than string.\n"); */
-
-  pop_n_elems(args);
-  cval_push_result(0, DISPATCH_PROPERTYGET);
 }
 
 /*   pike_add_function("`[]", f_cval_ind, "function(mixed:mixed)", 0); */
diff --git a/src/post_modules/CritBit/tree_source.H b/src/post_modules/CritBit/tree_source.H
index ea8ef1e5bd..567aa2058d 100644
--- a/src/post_modules/CritBit/tree_source.H
+++ b/src/post_modules/CritBit/tree_source.H
@@ -218,19 +218,15 @@ DOCEND()
      *! behaves as the inverse of create().
      */
     PIKEFUN mixed cast(string type) {
-	struct pike_string *mapping_t;
-	REF_MAKE_CONST_STRING(mapping_t, "mapping");
-
-	if (type == mapping_t) {
-	    pop_stack();
-	    cmod_CONCAT_EVAL(f_, tree_class, _cq__indices)(0);
-	    cmod_CONCAT_EVAL(f_, tree_class, _cq__values)(0);
-	    f_mkmapping(2);
-	    free_string(mapping_t);
-	    return;
-	}
-	free_string(mapping_t);
-	Pike_error("Cannot cast to %S\n", type);
+      pop_stack(); /* type as at least one more reference. */
+
+      if (type == literal_mapping_string) {
+        cmod_CONCAT_EVAL(f_, tree_class, _cq__indices)(0);
+        cmod_CONCAT_EVAL(f_, tree_class, _cq__values)(0);
+        f_mkmapping(2);
+      }
+      else
+        push_undefined();
     }
 
     /*! @decl mixed nth(int(0..) n)
diff --git a/src/post_modules/GTK2/source/gdkevent.pre b/src/post_modules/GTK2/source/gdkevent.pre
index fc2724e17b..23708c32d6 100644
--- a/src/post_modules/GTK2/source/gdkevent.pre
+++ b/src/post_modules/GTK2/source/gdkevent.pre
@@ -279,8 +279,11 @@ mixed cast(string to)
 
   if(!e) Pike_error("No event\n");
 
-  if( !args  || !is_same_string(Pike_sp[-args].u.string,_STR("mapping")) )
-    Pike_error("Can only cast to mapping\n");
+  if( !args  || Pike_sp[-args].u.string != literal_mapping_string )
+  {
+    pop_n_elems( args );
+    push_undefined();
+  }
   pop_n_elems( args );
 
   switch(e->type)
diff --git a/src/post_modules/GTK2/source/gdkrectangle.pre b/src/post_modules/GTK2/source/gdkrectangle.pre
index 54ef09d23b..6fa00712b1 100644
--- a/src/post_modules/GTK2/source/gdkrectangle.pre
+++ b/src/post_modules/GTK2/source/gdkrectangle.pre
@@ -42,10 +42,14 @@ mixed cast(string type)
 {
   struct pike_string *type;
   GdkRectangle *r=(GdkRectangle *)THIS->obj;
-  get_all_args("cast",args,"%t",&type);
 
-  if (is_same_string(type,_STR("mapping"))) {
-    pgtk2_pop_n_elems(args);
+  if (args!=1)
+    SIMPLE_TOO_FEW_ARGS_ERROR("cast",1);
+
+  type = Pike_sp[-args].u.string;
+  pgtk2_pop_n_elems(args);
+
+  if (type == literal_mapping_string) {
     ref_push_string(_STR("x"));
     push_int(r->x);
     ref_push_string(_STR("y"));
@@ -55,15 +59,14 @@ mixed cast(string type)
     ref_push_string(_STR("height"));
     push_int(r->height);
     f_aggregate_mapping(8);
-  } else if(is_same_string(type, _STR("array"))) {
-    pgtk2_pop_n_elems(args);
+  } else if(type == literal_array_string) {
     push_int(r->x);
     push_int(r->y);
     push_int(r->width);
     push_int(r->height);
     f_aggregate(4);
   } else {
-    Pike_error("Cannot cast to %S.\n",type);
+    push_undefined();
   }
 }
 
diff --git a/src/post_modules/SDL/SDL.cmod b/src/post_modules/SDL/SDL.cmod
index 4856ef7a40..e01fb3be1b 100644
--- a/src/post_modules/SDL/SDL.cmod
+++ b/src/post_modules/SDL/SDL.cmod
@@ -459,23 +459,17 @@ PIKECLASS Rect {
    *! associated with the corresponding names.
    */
   PIKEFUN mixed cast( string type )
+    flags ID_PROTECTED;
   {
-    struct pike_string *array_t;
-    struct pike_string *mapping_t;
-    REF_MAKE_CONST_STRING( array_t, "array" );
-    REF_MAKE_CONST_STRING( mapping_t, "mapping" );
-
-    if( type == array_t )
+    pop_stack(); /* type as at least one more reference. */
+    if( type == literal_array_string )
     {
-      pop_n_elems( args );
       push_int(THIS->rect.x);
       push_int(THIS->rect.y);
       push_int(THIS->rect.w);
       push_int(THIS->rect.h);
       f_aggregate(4);
-      return;
-    } else if( type == mapping_t ) {
-      pop_n_elems( args );
+    } else if( type == literla_mapping_string ) {
       push_text("x");
       push_int(THIS->rect.x);
       push_text("y");
@@ -485,10 +479,9 @@ PIKECLASS Rect {
       push_text("h");
       push_int(THIS->rect.h);
       f_aggregate_mapping(8);
-      return;
     }
-
-    Pike_error("Cannot cast to %S\n", type);
+    else
+      push_undefined();
   }
 }
 /*! @endclass Rect */
diff --git a/src/post_modules/_ADT/circular_list.cmod b/src/post_modules/_ADT/circular_list.cmod
index edec845c0a..c4c589c48d 100644
--- a/src/post_modules/_ADT/circular_list.cmod
+++ b/src/post_modules/_ADT/circular_list.cmod
@@ -13,6 +13,7 @@
 #include "interpret.h"
 #include "stralloc.h"
 #include "program.h"
+#include "pike_types.h"
 
 #include "program_id.h"
 
@@ -548,11 +549,10 @@ PIKECLASS CircularList
  */
 
   PIKEFUN mixed cast(string type)
+    flags ID_PROTECTED;
   {
-    struct pike_string *array_t;
-    MAKE_CONST_STRING( array_t, "array" );
-    
-    if (type == array_t)
+    pop_n_elems(args); /* type as at least one more reference. */
+    if (type == literal_array_string)
     {
       struct array *a;
       int end;
@@ -584,9 +584,7 @@ PIKECLASS CircularList
 
     }
     else
-    {
-      Pike_error("Cannot cast to %S\n", type);
-    }
+      push_undefined();
   }
 
   /*! @decl void clear()
diff --git a/src/post_modules/_ADT/sequence.cmod b/src/post_modules/_ADT/sequence.cmod
index c0357a5756..3e8c258ae3 100644
--- a/src/post_modules/_ADT/sequence.cmod
+++ b/src/post_modules/_ADT/sequence.cmod
@@ -14,6 +14,7 @@
 #include "stralloc.h"
 #include "program.h"
 #include "operators.h"
+#include "pike_types.h"
 
 #include "program_id.h"
 
@@ -429,19 +430,13 @@ PIKECLASS Sequence
  */
 
   PIKEFUN mixed cast(string type)
+    flags ID_PROTECTED;
   {
-    struct pike_string *array_t;
-    MAKE_CONST_STRING( array_t, "array" );
-    
-    if (type == array_t)
-    {
-           push_array(copy_array(THIS->a));
-      
-    }
+    pop_n_elems(args); /* type as at least one more reference. */
+    if (type == literal_array_string)
+      push_array(copy_array(THIS->a));
     else
-    {
-      Pike_error("Cannot cast to %S\n", type);
-    }
+      push_undefined();
   }
 
   /*! @decl void clear()
diff --git a/src/post_modules/_ADT/testsuite.in b/src/post_modules/_ADT/testsuite.in
index cc8b712250..9c9977b3bc 100644
--- a/src/post_modules/_ADT/testsuite.in
+++ b/src/post_modules/_ADT/testsuite.in
@@ -188,10 +188,7 @@ test_any(_ADT.Sequence a = _ADT.Sequence(({1,2,3,4,1,2,3,4}));
 *************************** test cast **************************************
 
 test_any_equal(_ADT.Sequence a = _ADT.Sequence(({1,2,3,4,1,2,3,4}));
-          	return a->cast("array"), ({1,2,3,4,1,2,3,4}))
-
-test_eval_error(_ADT.Sequence a = _ADT.Sequence(({1,2,3,4,1,2,3,4}));
-          	return a->cast("nisse"))
+          	return (array)a, ({1,2,3,4,1,2,3,4}))
 
 **************************** test clear ************************************
 
@@ -955,16 +952,13 @@ test_eval_error(_ADT.CircularList a = _ADT.CircularList(({1,2,3,4}));
 *************************** test cast **************************************
 
 test_any_equal(_ADT.CircularList a = _ADT.CircularList(({1,2,3,4,1,2,3,4}));
-          	return a->cast("array"), ({1,2,3,4,1,2,3,4}))
+          	return (array)a, ({1,2,3,4,1,2,3,4}))
 
 test_any_equal(_ADT.CircularList a = _ADT.CircularList(5);
 	       a->push_front(2);
 	       a->push_front(1);
 	       a->push_back(3);
-          	return a->cast("array"), ({1,2,3}))
-
-test_eval_error(_ADT.CircularList a = _ADT.CircularList(({1,2,3,4,1,2,3,4}));
-          	return a->cast("nisse"))
+          	return (array)a, ({1,2,3}))
 
 ************************ test allocate *************************************
 
diff --git a/src/post_modules/_Regexp_PCRE/module.pmod.in b/src/post_modules/_Regexp_PCRE/module.pmod.in
index 87fa886799..1d41314e50 100644
--- a/src/post_modules/_Regexp_PCRE/module.pmod.in
+++ b/src/post_modules/_Regexp_PCRE/module.pmod.in
@@ -316,16 +316,16 @@ class Plain
                
 /**** "internal" ***********************************************/
 
-   string _sprintf(int t,mapping fum)
+   protected string _sprintf(int t,mapping fum)
    {
       if (t=='t') return "Regexp.PCRE.Plain";
       return ::_sprintf(t,fum);
    }
 
-   string cast(string to)
+   protected string cast(string to)
    {
       if (to=="string") return pattern; 
-      else error("can't cast %t to %O\n",this,to);
+      return UNDEFINED;
    }
 }
 
-- 
GitLab