shithub: freetype+ttf2subf

Download patch

ref: 1b4d68cf901d18cadfef5c4433e78969cc5b6d46
parent: 232bd948fd37821d35e728ec20aeea971fb9616c
author: Werner Lemberg <[email protected]>
date: Sat Jan 10 14:56:28 EST 2015

* src/truetype/ttinterp.c (CUR): Remove by replacing with expansion.

This starts a series of patches that simplifies the code of the
bytecode interpreter.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2015-01-10  Werner Lemberg  <[email protected]>
+
+	* src/truetype/ttinterp.c (CUR): Remove by replacing with expansion.
+
+	This starts a series of patches that simplifies the code of the
+	bytecode interpreter.
+
 2014-12-30  Werner Lemberg  <[email protected]>
 
 	* Version 2.5.5 released.
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -92,8 +92,6 @@
 
 #ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */
 
-#define CUR  (*exc)                             /* see ttobjs.h */
-
   /*************************************************************************/
   /*                                                                       */
   /* This macro is used whenever `exec' is unused in a function, to avoid  */
@@ -103,8 +101,6 @@
 
 #else                                           /* static implementation */
 
-#define CUR  cur
-
 #define FT_UNUSED_EXEC  int  __dummy = __dummy
 
   static
@@ -132,8 +128,8 @@
 #define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )
 
 
-#define SUBPIXEL_HINTING                                                    \
-          ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
+#define SUBPIXEL_HINTING                                                     \
+          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
             TT_INTERPRETER_VERSION_38 )
 
 
@@ -164,25 +160,25 @@
           Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
 
 #define CUR_Func_move( z, p, d ) \
-          CUR.func_move( EXEC_ARG_ z, p, d )
+          exc->func_move( EXEC_ARG_ z, p, d )
 
 #define CUR_Func_move_orig( z, p, d ) \
-          CUR.func_move_orig( EXEC_ARG_ z, p, d )
+          exc->func_move_orig( EXEC_ARG_ z, p, d )
 
 #define CUR_Func_round( d, c ) \
-          CUR.func_round( EXEC_ARG_ d, c )
+          exc->func_round( EXEC_ARG_ d, c )
 
 #define CUR_Func_cur_ppem() \
-          CUR.func_cur_ppem( EXEC_ARG )
+          exc->func_cur_ppem( EXEC_ARG )
 
 #define CUR_Func_read_cvt( index ) \
-          CUR.func_read_cvt( EXEC_ARG_ index )
+          exc->func_read_cvt( EXEC_ARG_ index )
 
 #define CUR_Func_write_cvt( index, val ) \
-          CUR.func_write_cvt( EXEC_ARG_ index, val )
+          exc->func_write_cvt( EXEC_ARG_ index, val )
 
 #define CUR_Func_move_cvt( index, val ) \
-          CUR.func_move_cvt( EXEC_ARG_ index, val )
+          exc->func_move_cvt( EXEC_ARG_ index, val )
 
 #define CURRENT_Ratio() \
           Current_Ratio( EXEC_ARG )
@@ -204,16 +200,16 @@
 
 
 #define CUR_Func_project( v1, v2 )  \
-          CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
+          exc->func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 
 #define CUR_Func_dualproj( v1, v2 )  \
-          CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
+          exc->func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 
 #define CUR_fast_project( v ) \
-          CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
+          exc->func_project( EXEC_ARG_ (v)->x, (v)->y )
 
 #define CUR_fast_dualproj( v ) \
-          CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
+          exc->func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
 
 
   /*************************************************************************/
@@ -245,11 +241,11 @@
 #define FAILURE  1
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define GUESS_VECTOR( V )                                         \
-  if ( CUR.face->unpatented_hinting )                             \
-  {                                                               \
-    CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
-    CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
+#define GUESS_VECTOR( V )                                           \
+  if ( exc->face->unpatented_hinting )                              \
+  {                                                                 \
+    exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
+    exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
   }
 #else
 #define GUESS_VECTOR( V )
@@ -1639,24 +1635,24 @@
   static FT_Long
   Current_Ratio( EXEC_OP )
   {
-    if ( !CUR.tt_metrics.ratio )
+    if ( !exc->tt_metrics.ratio )
     {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-      if ( CUR.face->unpatented_hinting )
+      if ( exc->face->unpatented_hinting )
       {
-        if ( CUR.GS.both_x_axis )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+        if ( exc->GS.both_x_axis )
+          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
         else
-          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
       }
       else
 #endif
       {
-        if ( CUR.GS.projVector.y == 0 )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+        if ( exc->GS.projVector.y == 0 )
+          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
 
-        else if ( CUR.GS.projVector.x == 0 )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+        else if ( exc->GS.projVector.x == 0 )
+          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
 
         else
         {
@@ -1663,15 +1659,15 @@
           FT_F26Dot6  x, y;
 
 
-          x = TT_MulFix14( CUR.tt_metrics.x_ratio,
-                           CUR.GS.projVector.x );
-          y = TT_MulFix14( CUR.tt_metrics.y_ratio,
-                           CUR.GS.projVector.y );
-          CUR.tt_metrics.ratio = FT_Hypot( x, y );
+          x = TT_MulFix14( exc->tt_metrics.x_ratio,
+                           exc->GS.projVector.x );
+          y = TT_MulFix14( exc->tt_metrics.y_ratio,
+                           exc->GS.projVector.y );
+          exc->tt_metrics.ratio = FT_Hypot( x, y );
         }
       }
     }
-    return CUR.tt_metrics.ratio;
+    return exc->tt_metrics.ratio;
   }
 
 
@@ -1678,7 +1674,7 @@
   FT_CALLBACK_DEF( FT_Long )
   Current_Ppem( EXEC_OP )
   {
-    return CUR.tt_metrics.ppem;
+    return exc->tt_metrics.ppem;
   }
 
 
@@ -1685,7 +1681,7 @@
   FT_CALLBACK_DEF( FT_Long )
   Current_Ppem_Stretched( EXEC_OP )
   {
-    return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+    return FT_MulFix( exc->tt_metrics.ppem, CURRENT_Ratio() );
   }
 
 
@@ -1699,7 +1695,7 @@
   FT_CALLBACK_DEF( FT_F26Dot6 )
   Read_CVT( EXEC_OP_ FT_ULong  idx )
   {
-    return CUR.cvt[idx];
+    return exc->cvt[idx];
   }
 
 
@@ -1706,7 +1702,7 @@
   FT_CALLBACK_DEF( FT_F26Dot6 )
   Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )
   {
-    return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
+    return FT_MulFix( exc->cvt[idx], CURRENT_Ratio() );
   }
 
 
@@ -1714,7 +1710,7 @@
   Write_CVT( EXEC_OP_ FT_ULong    idx,
                       FT_F26Dot6  value )
   {
-    CUR.cvt[idx] = value;
+    exc->cvt[idx] = value;
   }
 
 
@@ -1722,7 +1718,7 @@
   Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
                                 FT_F26Dot6  value )
   {
-    CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
+    exc->cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
   }
 
 
@@ -1730,7 +1726,7 @@
   Move_CVT( EXEC_OP_ FT_ULong    idx,
                      FT_F26Dot6  value )
   {
-    CUR.cvt[idx] += value;
+    exc->cvt[idx] += value;
   }
 
 
@@ -1738,7 +1734,7 @@
   Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
                                FT_F26Dot6  value )
   {
-    CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
+    exc->cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
   }
 
 
@@ -1761,9 +1757,9 @@
   GetShortIns( EXEC_OP )
   {
     /* Reading a byte stream so there is no endianess (DaveP) */
-    CUR.IP += 2;
-    return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
-                         CUR.code[CUR.IP - 1]      );
+    exc->IP += 2;
+    return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
+                         exc->code[exc->IP - 1]      );
   }
 
 
@@ -1792,15 +1788,15 @@
 
     if ( aRange < 1 || aRange > 3 )
     {
-      CUR.error = FT_THROW( Bad_Argument );
+      exc->error = FT_THROW( Bad_Argument );
       return FAILURE;
     }
 
-    range = &CUR.codeRangeTable[aRange - 1];
+    range = &exc->codeRangeTable[aRange - 1];
 
     if ( range->base == NULL )     /* invalid coderange */
     {
-      CUR.error = FT_THROW( Invalid_CodeRange );
+      exc->error = FT_THROW( Invalid_CodeRange );
       return FAILURE;
     }
 
@@ -1810,14 +1806,14 @@
 
     if ( aIP > range->size )
     {
-      CUR.error = FT_THROW( Code_Overflow );
+      exc->error = FT_THROW( Code_Overflow );
       return FAILURE;
     }
 
-    CUR.code     = range->base;
-    CUR.codeSize = range->size;
-    CUR.IP       = aIP;
-    CUR.curRange = aRange;
+    exc->code     = range->base;
+    exc->codeSize = range->size;
+    exc->IP       = aIP;
+    exc->curRange = aRange;
 
     return SUCCESS;
   }
@@ -1849,28 +1845,28 @@
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
-    v = CUR.GS.freeVector.x;
+    v = exc->GS.freeVector.x;
 
     if ( v != 0 )
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( !SUBPIXEL_HINTING                                     ||
-           ( !CUR.ignore_x_mode                                ||
-             ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
+      if ( !SUBPIXEL_HINTING                                      ||
+           ( !exc->ignore_x_mode                                ||
+             ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
+        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
 
-    v = CUR.GS.freeVector.y;
+    v = exc->GS.freeVector.y;
 
     if ( v != 0 )
     {
-      zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
@@ -1903,18 +1899,18 @@
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
-    v = CUR.GS.freeVector.x;
+    v = exc->GS.freeVector.x;
 
     if ( v != 0 )
-      zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 
-    v = CUR.GS.freeVector.y;
+    v = exc->GS.freeVector.y;
 
     if ( v != 0 )
-      zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
   }
 
 
@@ -1936,8 +1932,8 @@
     FT_UNUSED_EXEC;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( !SUBPIXEL_HINTING  ||
-         !CUR.ignore_x_mode )
+    if ( !SUBPIXEL_HINTING   ||
+         !exc->ignore_x_mode )
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
       zone->cur[point].x += distance;
 
@@ -2277,19 +2273,19 @@
 
     if ( distance >= 0 )
     {
-      val = ( distance - CUR.phase + CUR.threshold + compensation ) &
-              -CUR.period;
-      val += CUR.phase;
+      val = ( distance - exc->phase + exc->threshold + compensation ) &
+              -exc->period;
+      val += exc->phase;
       if ( val < 0 )
-        val = CUR.phase;
+        val = exc->phase;
     }
     else
     {
-      val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
-               -CUR.period );
-      val -= CUR.phase;
+      val = -( ( exc->threshold - exc->phase - distance + compensation ) &
+               -exc->period );
+      val -= exc->phase;
       if ( val > 0 )
-        val = -CUR.phase;
+        val = -exc->phase;
     }
 
     return val;
@@ -2325,19 +2321,19 @@
 
     if ( distance >= 0 )
     {
-      val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
-                CUR.period ) * CUR.period;
-      val += CUR.phase;
+      val = ( ( distance - exc->phase + exc->threshold + compensation ) /
+                exc->period ) * exc->period;
+      val += exc->phase;
       if ( val < 0 )
-        val = CUR.phase;
+        val = exc->phase;
     }
     else
     {
-      val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
-                   CUR.period ) * CUR.period );
-      val -= CUR.phase;
+      val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
+                   exc->period ) * exc->period );
+      val -= exc->phase;
       if ( val > 0 )
-        val = -CUR.phase;
+        val = -exc->phase;
     }
 
     return val;
@@ -2361,35 +2357,35 @@
     switch ( round_mode )
     {
     case TT_Round_Off:
-      CUR.func_round = (TT_Round_Func)Round_None;
+      exc->func_round = (TT_Round_Func)Round_None;
       break;
 
     case TT_Round_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Grid;
       break;
 
     case TT_Round_Up_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
       break;
 
     case TT_Round_Down_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
       break;
 
     case TT_Round_To_Half_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
       break;
 
     case TT_Round_To_Double_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
       break;
 
     case TT_Round_Super:
-      CUR.func_round = (TT_Round_Func)Round_Super;
+      exc->func_round = (TT_Round_Func)Round_Super;
       break;
 
     case TT_Round_Super_45:
-      CUR.func_round = (TT_Round_Func)Round_Super_45;
+      exc->func_round = (TT_Round_Func)Round_Super_45;
       break;
     }
   }
@@ -2415,21 +2411,21 @@
     switch ( (FT_Int)( selector & 0xC0 ) )
     {
       case 0:
-        CUR.period = GridPeriod / 2;
+        exc->period = GridPeriod / 2;
         break;
 
       case 0x40:
-        CUR.period = GridPeriod;
+        exc->period = GridPeriod;
         break;
 
       case 0x80:
-        CUR.period = GridPeriod * 2;
+        exc->period = GridPeriod * 2;
         break;
 
       /* This opcode is reserved, but... */
 
       case 0xC0:
-        CUR.period = GridPeriod;
+        exc->period = GridPeriod;
         break;
     }
 
@@ -2436,30 +2432,30 @@
     switch ( (FT_Int)( selector & 0x30 ) )
     {
     case 0:
-      CUR.phase = 0;
+      exc->phase = 0;
       break;
 
     case 0x10:
-      CUR.phase = CUR.period / 4;
+      exc->phase = exc->period / 4;
       break;
 
     case 0x20:
-      CUR.phase = CUR.period / 2;
+      exc->phase = exc->period / 2;
       break;
 
     case 0x30:
-      CUR.phase = CUR.period * 3 / 4;
+      exc->phase = exc->period * 3 / 4;
       break;
     }
 
     if ( ( selector & 0x0F ) == 0 )
-      CUR.threshold = CUR.period - 1;
+      exc->threshold = exc->period - 1;
     else
-      CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
+      exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
 
-    CUR.period    /= 256;
-    CUR.phase     /= 256;
-    CUR.threshold /= 256;
+    exc->period    /= 256;
+    exc->phase     /= 256;
+    exc->threshold /= 256;
   }
 
 
@@ -2484,12 +2480,12 @@
                     FT_Pos  dy )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
     return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
-                        CUR.GS.projVector.x,
-                        CUR.GS.projVector.y );
+                        exc->GS.projVector.x,
+                        exc->GS.projVector.y );
   }
 
 
@@ -2514,8 +2510,8 @@
                          FT_Pos  dy )
   {
     return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
-                        CUR.GS.dualVector.x,
-                        CUR.GS.dualVector.y );
+                        exc->GS.dualVector.x,
+                        exc->GS.dualVector.y );
   }
 
 
@@ -2586,87 +2582,87 @@
   Compute_Funcs( EXEC_OP )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
       /* If both vectors point rightwards along the x axis, set             */
       /* `both-x-axis' true, otherwise set it false.  The x values only     */
       /* need be tested because the vector has been normalised to a unit    */
       /* vector of length 0x4000 = unity.                                   */
-      CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
-                                      CUR.GS.freeVector.x == 0x4000 );
+      exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
+                                       exc->GS.freeVector.x == 0x4000 );
 
       /* Throw away projection and freedom vector information */
       /* because the patents don't allow them to be stored.   */
       /* The relevant US Patents are 5155805 and 5325479.     */
-      CUR.GS.projVector.x = 0;
-      CUR.GS.projVector.y = 0;
-      CUR.GS.freeVector.x = 0;
-      CUR.GS.freeVector.y = 0;
+      exc->GS.projVector.x = 0;
+      exc->GS.projVector.y = 0;
+      exc->GS.freeVector.x = 0;
+      exc->GS.freeVector.y = 0;
 
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
-        CUR.func_project   = Project_x;
-        CUR.func_move      = Direct_Move_X;
-        CUR.func_move_orig = Direct_Move_Orig_X;
+        exc->func_project   = Project_x;
+        exc->func_move      = Direct_Move_X;
+        exc->func_move_orig = Direct_Move_Orig_X;
       }
       else
       {
-        CUR.func_project   = Project_y;
-        CUR.func_move      = Direct_Move_Y;
-        CUR.func_move_orig = Direct_Move_Orig_Y;
+        exc->func_project   = Project_y;
+        exc->func_move      = Direct_Move_Y;
+        exc->func_move_orig = Direct_Move_Orig_Y;
       }
 
-      if ( CUR.GS.dualVector.x == 0x4000 )
-        CUR.func_dualproj = Project_x;
-      else if ( CUR.GS.dualVector.y == 0x4000 )
-        CUR.func_dualproj = Project_y;
+      if ( exc->GS.dualVector.x == 0x4000 )
+        exc->func_dualproj = Project_x;
+      else if ( exc->GS.dualVector.y == 0x4000 )
+        exc->func_dualproj = Project_y;
       else
-        CUR.func_dualproj = Dual_Project;
+        exc->func_dualproj = Dual_Project;
 
       /* Force recalculation of cached aspect ratio */
-      CUR.tt_metrics.ratio = 0;
+      exc->tt_metrics.ratio = 0;
 
       return;
     }
 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
 
-    if ( CUR.GS.freeVector.x == 0x4000 )
-      CUR.F_dot_P = CUR.GS.projVector.x;
-    else if ( CUR.GS.freeVector.y == 0x4000 )
-      CUR.F_dot_P = CUR.GS.projVector.y;
+    if ( exc->GS.freeVector.x == 0x4000 )
+      exc->F_dot_P = exc->GS.projVector.x;
+    else if ( exc->GS.freeVector.y == 0x4000 )
+      exc->F_dot_P = exc->GS.projVector.y;
     else
-      CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
-                      (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
-                    14;
+      exc->F_dot_P = ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
+                       (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >>
+                     14;
 
-    if ( CUR.GS.projVector.x == 0x4000 )
-      CUR.func_project = (TT_Project_Func)Project_x;
-    else if ( CUR.GS.projVector.y == 0x4000 )
-      CUR.func_project = (TT_Project_Func)Project_y;
+    if ( exc->GS.projVector.x == 0x4000 )
+      exc->func_project = (TT_Project_Func)Project_x;
+    else if ( exc->GS.projVector.y == 0x4000 )
+      exc->func_project = (TT_Project_Func)Project_y;
     else
-      CUR.func_project = (TT_Project_Func)Project;
+      exc->func_project = (TT_Project_Func)Project;
 
-    if ( CUR.GS.dualVector.x == 0x4000 )
-      CUR.func_dualproj = (TT_Project_Func)Project_x;
-    else if ( CUR.GS.dualVector.y == 0x4000 )
-      CUR.func_dualproj = (TT_Project_Func)Project_y;
+    if ( exc->GS.dualVector.x == 0x4000 )
+      exc->func_dualproj = (TT_Project_Func)Project_x;
+    else if ( exc->GS.dualVector.y == 0x4000 )
+      exc->func_dualproj = (TT_Project_Func)Project_y;
     else
-      CUR.func_dualproj = (TT_Project_Func)Dual_Project;
+      exc->func_dualproj = (TT_Project_Func)Dual_Project;
 
-    CUR.func_move      = (TT_Move_Func)Direct_Move;
-    CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
+    exc->func_move      = (TT_Move_Func)Direct_Move;
+    exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
 
-    if ( CUR.F_dot_P == 0x4000L )
+    if ( exc->F_dot_P == 0x4000L )
     {
-      if ( CUR.GS.freeVector.x == 0x4000 )
+      if ( exc->GS.freeVector.x == 0x4000 )
       {
-        CUR.func_move      = (TT_Move_Func)Direct_Move_X;
-        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
+        exc->func_move      = (TT_Move_Func)Direct_Move_X;
+        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
       }
-      else if ( CUR.GS.freeVector.y == 0x4000 )
+      else if ( exc->GS.freeVector.y == 0x4000 )
       {
-        CUR.func_move      = (TT_Move_Func)Direct_Move_Y;
-        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
+        exc->func_move      = (TT_Move_Func)Direct_Move_Y;
+        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
       }
     }
 
@@ -2673,11 +2669,11 @@
     /* at small sizes, F_dot_P can become too small, resulting   */
     /* in overflows and `spikes' in a number of glyphs like `w'. */
 
-    if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
-      CUR.F_dot_P = 0x4000L;
+    if ( FT_ABS( exc->F_dot_P ) < 0x400L )
+      exc->F_dot_P = 0x4000L;
 
     /* Disable cached aspect ratio */
-    CUR.tt_metrics.ratio = 0;
+    exc->tt_metrics.ratio = 0;
   }
 
 
@@ -2753,16 +2749,16 @@
     FT_Vector*  p2;
 
 
-    if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
-         BOUNDS( aIdx2, CUR.zp1.n_points ) )
+    if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
+         BOUNDS( aIdx2, exc->zp1.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return FAILURE;
     }
 
-    p1 = CUR.zp1.cur + aIdx2;
-    p2 = CUR.zp2.cur + aIdx1;
+    p1 = exc->zp1.cur + aIdx2;
+    p2 = exc->zp2.cur + aIdx1;
 
     A = p1->x - p2->x;
     B = p1->y - p2->y;
@@ -2797,89 +2793,89 @@
   /*                                                                  */
   /* They are all defined there.                                      */
 
-#define DO_SVTCA                            \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.freeVector.x = A;                \
-    CUR.GS.projVector.x = A;                \
-    CUR.GS.dualVector.x = A;                \
-                                            \
-    CUR.GS.freeVector.y = B;                \
-    CUR.GS.projVector.y = B;                \
-    CUR.GS.dualVector.y = B;                \
-                                            \
-    COMPUTE_Funcs();                        \
+#define DO_SVTCA                             \
+  {                                          \
+    FT_Short  A, B;                          \
+                                             \
+                                             \
+    A = (FT_Short)( exc->opcode & 1 ) << 14; \
+    B = A ^ (FT_Short)0x4000;                \
+                                             \
+    exc->GS.freeVector.x = A;                \
+    exc->GS.projVector.x = A;                \
+    exc->GS.dualVector.x = A;                \
+                                             \
+    exc->GS.freeVector.y = B;                \
+    exc->GS.projVector.y = B;                \
+    exc->GS.dualVector.y = B;                \
+                                             \
+    COMPUTE_Funcs();                         \
   }
 
 
-#define DO_SPVTCA                           \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.projVector.x = A;                \
-    CUR.GS.dualVector.x = A;                \
-                                            \
-    CUR.GS.projVector.y = B;                \
-    CUR.GS.dualVector.y = B;                \
-                                            \
-    GUESS_VECTOR( freeVector );             \
-                                            \
-    COMPUTE_Funcs();                        \
+#define DO_SPVTCA                            \
+  {                                          \
+    FT_Short  A, B;                          \
+                                             \
+                                             \
+    A = (FT_Short)( exc->opcode & 1 ) << 14; \
+    B = A ^ (FT_Short)0x4000;                \
+                                             \
+    exc->GS.projVector.x = A;                \
+    exc->GS.dualVector.x = A;                \
+                                             \
+    exc->GS.projVector.y = B;                \
+    exc->GS.dualVector.y = B;                \
+                                             \
+    GUESS_VECTOR( freeVector );              \
+                                             \
+    COMPUTE_Funcs();                         \
   }
 
 
-#define DO_SFVTCA                           \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.freeVector.x = A;                \
-    CUR.GS.freeVector.y = B;                \
-                                            \
-    GUESS_VECTOR( projVector );             \
-                                            \
-    COMPUTE_Funcs();                        \
+#define DO_SFVTCA                            \
+  {                                          \
+    FT_Short  A, B;                          \
+                                             \
+                                             \
+    A = (FT_Short)( exc->opcode & 1 ) << 14; \
+    B = A ^ (FT_Short)0x4000;                \
+                                             \
+    exc->GS.freeVector.x = A;                \
+    exc->GS.freeVector.y = B;                \
+                                             \
+    GUESS_VECTOR( projVector );              \
+                                             \
+    COMPUTE_Funcs();                         \
   }
 
 
-#define DO_SPVTL                                      \
-    if ( INS_SxVTL( (FT_UShort)args[1],               \
-                    (FT_UShort)args[0],               \
-                    CUR.opcode,                       \
-                    &CUR.GS.projVector ) == SUCCESS ) \
-    {                                                 \
-      CUR.GS.dualVector = CUR.GS.projVector;          \
-      GUESS_VECTOR( freeVector );                     \
-      COMPUTE_Funcs();                                \
+#define DO_SPVTL                                       \
+    if ( INS_SxVTL( (FT_UShort)args[1],                \
+                    (FT_UShort)args[0],                \
+                    exc->opcode,                       \
+                    &exc->GS.projVector ) == SUCCESS ) \
+    {                                                  \
+      exc->GS.dualVector = exc->GS.projVector;         \
+      GUESS_VECTOR( freeVector );                      \
+      COMPUTE_Funcs();                                 \
     }
 
 
-#define DO_SFVTL                                      \
-    if ( INS_SxVTL( (FT_UShort)args[1],               \
-                    (FT_UShort)args[0],               \
-                    CUR.opcode,                       \
-                    &CUR.GS.freeVector ) == SUCCESS ) \
-    {                                                 \
-      GUESS_VECTOR( projVector );                     \
-      COMPUTE_Funcs();                                \
+#define DO_SFVTL                                       \
+    if ( INS_SxVTL( (FT_UShort)args[1],                \
+                    (FT_UShort)args[0],                \
+                    exc->opcode,                       \
+                    &exc->GS.freeVector ) == SUCCESS ) \
+    {                                                  \
+      GUESS_VECTOR( projVector );                      \
+      COMPUTE_Funcs();                                 \
     }
 
 
-#define DO_SFVTPV                          \
-    GUESS_VECTOR( projVector );            \
-    CUR.GS.freeVector = CUR.GS.projVector; \
+#define DO_SFVTPV                            \
+    GUESS_VECTOR( projVector );              \
+    exc->GS.freeVector = exc->GS.projVector; \
     COMPUTE_Funcs();
 
 
@@ -2895,9 +2891,9 @@
     S = (FT_Short)args[0];                      \
     X = (FT_Long)S;                             \
                                                 \
-    NORMalize( X, Y, &CUR.GS.projVector );      \
+    NORMalize( X, Y, &exc->GS.projVector );     \
                                                 \
-    CUR.GS.dualVector = CUR.GS.projVector;      \
+    exc->GS.dualVector = exc->GS.projVector;    \
     GUESS_VECTOR( freeVector );                 \
     COMPUTE_Funcs();                            \
   }
@@ -2915,7 +2911,7 @@
     S = (FT_Short)args[0];                      \
     X = S;                                      \
                                                 \
-    NORMalize( X, Y, &CUR.GS.freeVector );      \
+    NORMalize( X, Y, &exc->GS.freeVector );     \
     GUESS_VECTOR( projVector );                 \
     COMPUTE_Funcs();                            \
   }
@@ -2922,138 +2918,138 @@
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GPV                                   \
-    if ( CUR.face->unpatented_hinting )          \
-    {                                            \
-      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
-      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
-    }                                            \
-    else                                         \
-    {                                            \
-      args[0] = CUR.GS.projVector.x;             \
-      args[1] = CUR.GS.projVector.y;             \
+#define DO_GPV                                    \
+    if ( exc->face->unpatented_hinting )          \
+    {                                             \
+      args[0] = exc->GS.both_x_axis ? 0x4000 : 0; \
+      args[1] = exc->GS.both_x_axis ? 0 : 0x4000; \
+    }                                             \
+    else                                          \
+    {                                             \
+      args[0] = exc->GS.projVector.x;             \
+      args[1] = exc->GS.projVector.y;             \
     }
 #else
-#define DO_GPV                                   \
-    args[0] = CUR.GS.projVector.x;               \
-    args[1] = CUR.GS.projVector.y;
+#define DO_GPV                                    \
+    args[0] = exc->GS.projVector.x;               \
+    args[1] = exc->GS.projVector.y;
 #endif
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GFV                                   \
-    if ( CUR.face->unpatented_hinting )          \
-    {                                            \
-      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
-      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
-    }                                            \
-    else                                         \
-    {                                            \
-      args[0] = CUR.GS.freeVector.x;             \
-      args[1] = CUR.GS.freeVector.y;             \
+#define DO_GFV                                    \
+    if ( exc->face->unpatented_hinting )          \
+    {                                             \
+      args[0] = exc->GS.both_x_axis ? 0x4000 : 0; \
+      args[1] = exc->GS.both_x_axis ? 0 : 0x4000; \
+    }                                             \
+    else                                          \
+    {                                             \
+      args[0] = exc->GS.freeVector.x;             \
+      args[1] = exc->GS.freeVector.y;             \
     }
 #else
-#define DO_GFV                                   \
-    args[0] = CUR.GS.freeVector.x;               \
-    args[1] = CUR.GS.freeVector.y;
+#define DO_GFV                                    \
+    args[0] = exc->GS.freeVector.x;               \
+    args[1] = exc->GS.freeVector.y;
 #endif
 
 
-#define DO_SRP0                      \
-    CUR.GS.rp0 = (FT_UShort)args[0];
+#define DO_SRP0                       \
+    exc->GS.rp0 = (FT_UShort)args[0];
 
 
-#define DO_SRP1                      \
-    CUR.GS.rp1 = (FT_UShort)args[0];
+#define DO_SRP1                       \
+    exc->GS.rp1 = (FT_UShort)args[0];
 
 
-#define DO_SRP2                      \
-    CUR.GS.rp2 = (FT_UShort)args[0];
+#define DO_SRP2                       \
+    exc->GS.rp2 = (FT_UShort)args[0];
 
 
-#define DO_RTHG                                         \
-    CUR.GS.round_state = TT_Round_To_Half_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+#define DO_RTHG                                          \
+    exc->GS.round_state = TT_Round_To_Half_Grid;         \
+    exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
 
 
-#define DO_RTG                                     \
-    CUR.GS.round_state = TT_Round_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Grid;
+#define DO_RTG                                      \
+    exc->GS.round_state = TT_Round_To_Grid;         \
+    exc->func_round = (TT_Round_Func)Round_To_Grid;
 
 
-#define DO_RTDG                                           \
-    CUR.GS.round_state = TT_Round_To_Double_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+#define DO_RTDG                                            \
+    exc->GS.round_state = TT_Round_To_Double_Grid;         \
+    exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
 
 
-#define DO_RUTG                                       \
-    CUR.GS.round_state = TT_Round_Up_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+#define DO_RUTG                                        \
+    exc->GS.round_state = TT_Round_Up_To_Grid;         \
+    exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
 
 
-#define DO_RDTG                                         \
-    CUR.GS.round_state = TT_Round_Down_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+#define DO_RDTG                                          \
+    exc->GS.round_state = TT_Round_Down_To_Grid;         \
+    exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
 
 
-#define DO_ROFF                                 \
-    CUR.GS.round_state = TT_Round_Off;          \
-    CUR.func_round = (TT_Round_Func)Round_None;
+#define DO_ROFF                                  \
+    exc->GS.round_state = TT_Round_Off;          \
+    exc->func_round = (TT_Round_Func)Round_None;
 
 
-#define DO_SROUND                                \
-    SET_SuperRound( 0x4000, args[0] );           \
-    CUR.GS.round_state = TT_Round_Super;         \
-    CUR.func_round = (TT_Round_Func)Round_Super;
+#define DO_SROUND                                 \
+    SET_SuperRound( 0x4000, args[0] );            \
+    exc->GS.round_state = TT_Round_Super;         \
+    exc->func_round = (TT_Round_Func)Round_Super;
 
 
-#define DO_S45ROUND                                 \
-    SET_SuperRound( 0x2D41, args[0] );              \
-    CUR.GS.round_state = TT_Round_Super_45;         \
-    CUR.func_round = (TT_Round_Func)Round_Super_45;
+#define DO_S45ROUND                                  \
+    SET_SuperRound( 0x2D41, args[0] );               \
+    exc->GS.round_state = TT_Round_Super_45;         \
+    exc->func_round = (TT_Round_Func)Round_Super_45;
 
 
-#define DO_SLOOP                            \
-    if ( args[0] < 0 )                      \
-      CUR.error = FT_THROW( Bad_Argument ); \
-    else                                    \
-      CUR.GS.loop = args[0];
+#define DO_SLOOP                             \
+    if ( args[0] < 0 )                       \
+      exc->error = FT_THROW( Bad_Argument ); \
+    else                                     \
+      exc->GS.loop = args[0];
 
 
-#define DO_SMD                         \
-    CUR.GS.minimum_distance = args[0];
+#define DO_SMD                          \
+    exc->GS.minimum_distance = args[0];
 
 
-#define DO_SCVTCI                                     \
-    CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
+#define DO_SCVTCI                                      \
+    exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
 
 
-#define DO_SSWCI                                     \
-    CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
+#define DO_SSWCI                                      \
+    exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
 
 
-#define DO_SSW                                                     \
-    CUR.GS.single_width_value = FT_MulFix( args[0],                \
-                                           CUR.tt_metrics.scale );
+#define DO_SSW                                                      \
+    exc->GS.single_width_value = FT_MulFix( args[0],                \
+                                           exc->tt_metrics.scale );
 
 
-#define DO_FLIPON            \
-    CUR.GS.auto_flip = TRUE;
+#define DO_FLIPON             \
+    exc->GS.auto_flip = TRUE;
 
 
-#define DO_FLIPOFF            \
-    CUR.GS.auto_flip = FALSE;
+#define DO_FLIPOFF             \
+    exc->GS.auto_flip = FALSE;
 
 
-#define DO_SDB                              \
-    CUR.GS.delta_base = (FT_UShort)args[0];
+#define DO_SDB                               \
+    exc->GS.delta_base = (FT_UShort)args[0];
 
 
-#define DO_SDS                                 \
-    if ( (FT_ULong)args[0] > 6UL )             \
-      CUR.error = FT_THROW( Bad_Argument );    \
-    else                                       \
-      CUR.GS.delta_shift = (FT_UShort)args[0];
+#define DO_SDS                                  \
+    if ( (FT_ULong)args[0] > 6UL )              \
+      exc->error = FT_THROW( Bad_Argument );    \
+    else                                        \
+      exc->GS.delta_shift = (FT_UShort)args[0];
 
 
 #define DO_MD  /* nothing */
@@ -3067,8 +3063,8 @@
   /*       we thus decide to return only the ppem.                     */
 #if 0
 
-#define DO_MPS                       \
-    args[0] = CUR.metrics.pointSize;
+#define DO_MPS                        \
+    args[0] = exc->metrics.pointSize;
 
 #else
 
@@ -3082,8 +3078,8 @@
     args[1] = args[0];
 
 
-#define DO_CLEAR     \
-    CUR.new_top = 0;
+#define DO_CLEAR      \
+    exc->new_top = 0;
 
 
 #define DO_SWAP        \
@@ -3097,64 +3093,64 @@
   }
 
 
-#define DO_DEPTH       \
-    args[0] = CUR.top;
+#define DO_DEPTH        \
+    args[0] = exc->top;
 
 
-#define DO_CINDEX                                  \
-  {                                                \
-    FT_Long  L;                                    \
-                                                   \
-                                                   \
-    L = args[0];                                   \
-                                                   \
-    if ( L <= 0 || L > CUR.args )                  \
-    {                                              \
-      if ( CUR.pedantic_hinting )                  \
-        CUR.error = FT_THROW( Invalid_Reference ); \
-      args[0] = 0;                                 \
-    }                                              \
-    else                                           \
-      args[0] = CUR.stack[CUR.args - L];           \
+#define DO_CINDEX                                   \
+  {                                                 \
+    FT_Long  L;                                     \
+                                                    \
+                                                    \
+    L = args[0];                                    \
+                                                    \
+    if ( L <= 0 || L > exc->args )                  \
+    {                                               \
+      if ( exc->pedantic_hinting )                  \
+        exc->error = FT_THROW( Invalid_Reference ); \
+      args[0] = 0;                                  \
+    }                                               \
+    else                                            \
+      args[0] = exc->stack[exc->args - L];          \
   }
 
 
-#define DO_JROT                                                    \
-    if ( args[1] != 0 )                                            \
-    {                                                              \
-      if ( args[0] == 0 && CUR.args == 0 )                         \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.IP += args[0];                                           \
-      if ( CUR.IP < 0                                           || \
-           ( CUR.callTop > 0                                  &&   \
-             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.step_ins = FALSE;                                        \
+#define DO_JROT                                                       \
+    if ( args[1] != 0 )                                               \
+    {                                                                 \
+      if ( args[0] == 0 && exc->args == 0 )                           \
+        exc->error = FT_THROW( Bad_Argument );                        \
+      exc->IP += args[0];                                             \
+      if ( exc->IP < 0                                             || \
+           ( exc->callTop > 0                                    &&   \
+             exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )  \
+        exc->error = FT_THROW( Bad_Argument );                        \
+      exc->step_ins = FALSE;                                          \
     }
 
 
-#define DO_JMPR                                                  \
-    if ( args[0] == 0 && CUR.args == 0 )                         \
-      CUR.error = FT_THROW( Bad_Argument );                      \
-    CUR.IP += args[0];                                           \
-    if ( CUR.IP < 0                                           || \
-         ( CUR.callTop > 0                                  &&   \
-           CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-      CUR.error = FT_THROW( Bad_Argument );                      \
-    CUR.step_ins = FALSE;
+#define DO_JMPR                                                     \
+    if ( args[0] == 0 && exc->args == 0 )                           \
+      exc->error = FT_THROW( Bad_Argument );                        \
+    exc->IP += args[0];                                             \
+    if ( exc->IP < 0                                             || \
+         ( exc->callTop > 0                                    &&   \
+           exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )  \
+      exc->error = FT_THROW( Bad_Argument );                        \
+    exc->step_ins = FALSE;
 
 
-#define DO_JROF                                                    \
-    if ( args[1] == 0 )                                            \
-    {                                                              \
-      if ( args[0] == 0 && CUR.args == 0 )                         \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.IP += args[0];                                           \
-      if ( CUR.IP < 0                                           || \
-           ( CUR.callTop > 0                                  &&   \
-             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.step_ins = FALSE;                                        \
+#define DO_JROF                                                       \
+    if ( args[1] == 0 )                                               \
+    {                                                                 \
+      if ( args[0] == 0 && exc->args == 0 )                           \
+        exc->error = FT_THROW( Bad_Argument );                        \
+      exc->IP += args[0];                                             \
+      if ( exc->IP < 0                                             || \
+           ( exc->callTop > 0                                    &&   \
+             exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )  \
+        exc->error = FT_THROW( Bad_Argument );                        \
+      exc->step_ins = FALSE;                                          \
     }
 
 
@@ -3212,7 +3208,7 @@
 
 #define DO_DIV                                               \
     if ( args[1] == 0 )                                      \
-      CUR.error = FT_THROW( Divide_By_Zero );                \
+      exc->error = FT_THROW( Divide_By_Zero );               \
     else                                                     \
       args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
 
@@ -3229,7 +3225,7 @@
     args[0] = -args[0];
 
 
-#define DO_FLOOR    \
+#define DO_FLOOR                       \
     args[0] = FT_PIX_FLOOR( args[0] );
 
 
@@ -3238,79 +3234,79 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
-#define DO_RS                                             \
-   {                                                      \
-     FT_ULong  I = (FT_ULong)args[0];                     \
-                                                          \
-                                                          \
-     if ( BOUNDSL( I, CUR.storeSize ) )                   \
-     {                                                    \
-       if ( CUR.pedantic_hinting )                        \
-         ARRAY_BOUND_ERROR;                               \
-       else                                               \
-         args[0] = 0;                                     \
-     }                                                    \
-     else                                                 \
-     {                                                    \
-       /* subpixel hinting - avoid Typeman Dstroke and */ \
-       /* IStroke and Vacuform rounds                  */ \
-                                                          \
-       if ( SUBPIXEL_HINTING                           && \
-            CUR.ignore_x_mode                          && \
-            ( ( I == 24                            &&     \
-                ( CUR.face->sph_found_func_flags &        \
-                  ( SPH_FDEF_SPACING_1 |                  \
-                    SPH_FDEF_SPACING_2 )         ) ) ||   \
-              ( I == 22                      &&           \
-                ( CUR.sph_in_func_flags    &              \
-                  SPH_FDEF_TYPEMAN_STROKES ) )       ||   \
-              ( I == 8                             &&     \
-                ( CUR.face->sph_found_func_flags &        \
-                  SPH_FDEF_VACUFORM_ROUND_1      ) &&     \
-                  CUR.iup_called                   ) ) )  \
-         args[0] = 0;                                     \
-       else                                               \
-         args[0] = CUR.storage[I];                        \
-     }                                                    \
+#define DO_RS                                              \
+   {                                                       \
+     FT_ULong  I = (FT_ULong)args[0];                      \
+                                                           \
+                                                           \
+     if ( BOUNDSL( I, exc->storeSize ) )                   \
+     {                                                     \
+       if ( exc->pedantic_hinting )                        \
+         ARRAY_BOUND_ERROR;                                \
+       else                                                \
+         args[0] = 0;                                      \
+     }                                                     \
+     else                                                  \
+     {                                                     \
+       /* subpixel hinting - avoid Typeman Dstroke and */  \
+       /* IStroke and Vacuform rounds                  */  \
+                                                           \
+       if ( SUBPIXEL_HINTING                            && \
+            exc->ignore_x_mode                          && \
+            ( ( I == 24                             &&     \
+                ( exc->face->sph_found_func_flags &        \
+                  ( SPH_FDEF_SPACING_1 |                   \
+                    SPH_FDEF_SPACING_2 )          ) ) ||   \
+              ( I == 22                      &&            \
+                ( exc->sph_in_func_flags   &               \
+                  SPH_FDEF_TYPEMAN_STROKES ) )        ||   \
+              ( I == 8                              &&     \
+                ( exc->face->sph_found_func_flags &        \
+                  SPH_FDEF_VACUFORM_ROUND_1       ) &&     \
+                exc->iup_called                     ) ) )  \
+         args[0] = 0;                                      \
+       else                                                \
+         args[0] = exc->storage[I];                        \
+     }                                                     \
    }
 
 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-#define DO_RS                           \
-   {                                    \
-     FT_ULong  I = (FT_ULong)args[0];   \
-                                        \
-                                        \
-     if ( BOUNDSL( I, CUR.storeSize ) ) \
-     {                                  \
-       if ( CUR.pedantic_hinting )      \
-       {                                \
-         ARRAY_BOUND_ERROR;             \
-       }                                \
-       else                             \
-         args[0] = 0;                   \
-     }                                  \
-     else                               \
-       args[0] = CUR.storage[I];        \
+#define DO_RS                            \
+   {                                     \
+     FT_ULong  I = (FT_ULong)args[0];    \
+                                         \
+                                         \
+     if ( BOUNDSL( I, exc->storeSize ) ) \
+     {                                   \
+       if ( exc->pedantic_hinting )      \
+       {                                 \
+         ARRAY_BOUND_ERROR;              \
+       }                                 \
+       else                              \
+         args[0] = 0;                    \
+     }                                   \
+     else                                \
+       args[0] = exc->storage[I];        \
    }
 
 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
 
-#define DO_WS                           \
-   {                                    \
-     FT_ULong  I = (FT_ULong)args[0];   \
-                                        \
-                                        \
-     if ( BOUNDSL( I, CUR.storeSize ) ) \
-     {                                  \
-       if ( CUR.pedantic_hinting )      \
-       {                                \
-         ARRAY_BOUND_ERROR;             \
-       }                                \
-     }                                  \
-     else                               \
-       CUR.storage[I] = args[1];        \
+#define DO_WS                            \
+   {                                     \
+     FT_ULong  I = (FT_ULong)args[0];    \
+                                         \
+                                         \
+     if ( BOUNDSL( I, exc->storeSize ) ) \
+     {                                   \
+       if ( exc->pedantic_hinting )      \
+       {                                 \
+         ARRAY_BOUND_ERROR;              \
+       }                                 \
+     }                                   \
+     else                                \
+       exc->storage[I] = args[1];        \
    }
 
 
@@ -3319,9 +3315,9 @@
      FT_ULong  I = (FT_ULong)args[0];    \
                                          \
                                          \
-     if ( BOUNDSL( I, CUR.cvtSize ) )    \
+     if ( BOUNDSL( I, exc->cvtSize ) )   \
      {                                   \
-       if ( CUR.pedantic_hinting )       \
+       if ( exc->pedantic_hinting )      \
        {                                 \
          ARRAY_BOUND_ERROR;              \
        }                                 \
@@ -3338,9 +3334,9 @@
      FT_ULong  I = (FT_ULong)args[0];    \
                                          \
                                          \
-     if ( BOUNDSL( I, CUR.cvtSize ) )    \
+     if ( BOUNDSL( I, exc->cvtSize ) )   \
      {                                   \
-       if ( CUR.pedantic_hinting )       \
+       if ( exc->pedantic_hinting )      \
        {                                 \
          ARRAY_BOUND_ERROR;              \
        }                                 \
@@ -3350,36 +3346,36 @@
    }
 
 
-#define DO_WCVTF                                                \
-   {                                                            \
-     FT_ULong  I = (FT_ULong)args[0];                           \
-                                                                \
-                                                                \
-     if ( BOUNDSL( I, CUR.cvtSize ) )                           \
-     {                                                          \
-       if ( CUR.pedantic_hinting )                              \
-       {                                                        \
-         ARRAY_BOUND_ERROR;                                     \
-       }                                                        \
-     }                                                          \
-     else                                                       \
-       CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
+#define DO_WCVTF                                                  \
+   {                                                              \
+     FT_ULong  I = (FT_ULong)args[0];                             \
+                                                                  \
+                                                                  \
+     if ( BOUNDSL( I, exc->cvtSize ) )                            \
+     {                                                            \
+       if ( exc->pedantic_hinting )                               \
+       {                                                          \
+         ARRAY_BOUND_ERROR;                                       \
+       }                                                          \
+     }                                                            \
+     else                                                         \
+       exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale ); \
    }
 
 
-#define DO_DEBUG                          \
-    CUR.error = FT_THROW( Debug_OpCode );
+#define DO_DEBUG                           \
+    exc->error = FT_THROW( Debug_OpCode );
 
 
-#define DO_ROUND                                                   \
-    args[0] = CUR_Func_round(                                      \
-                args[0],                                           \
-                CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
+#define DO_ROUND                                                    \
+    args[0] = CUR_Func_round(                                       \
+                args[0],                                            \
+                exc->tt_metrics.compensations[exc->opcode - 0x68] );
 
 
-#define DO_NROUND                                                            \
-    args[0] = ROUND_None( args[0],                                           \
-                          CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
+#define DO_NROUND                                                             \
+    args[0] = ROUND_None( args[0],                                            \
+                          exc->tt_metrics.compensations[exc->opcode - 0x6C] );
 
 
 #define DO_MAX               \
@@ -3396,10 +3392,10 @@
 
 
 #undef  ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR                        \
-    {                                            \
-      CUR.error = FT_THROW( Invalid_Reference ); \
-      return;                                    \
+#define ARRAY_BOUND_ERROR                         \
+    {                                             \
+      exc->error = FT_THROW( Invalid_Reference ); \
+      return;                                     \
     }
 
 
@@ -4375,20 +4371,20 @@
 
     L = args[0];
 
-    if ( L <= 0 || L > CUR.args )
+    if ( L <= 0 || L > exc->args )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
     }
     else
     {
-      K = CUR.stack[CUR.args - L];
+      K = exc->stack[exc->args - L];
 
-      FT_ARRAY_MOVE( &CUR.stack[CUR.args - L    ],
-                     &CUR.stack[CUR.args - L + 1],
+      FT_ARRAY_MOVE( &exc->stack[exc->args - L    ],
+                     &exc->stack[exc->args - L + 1],
                      ( L - 1 ) );
 
-      CUR.stack[CUR.args - 1] = K;
+      exc->stack[exc->args - 1] = K;
     }
   }
 
@@ -4429,26 +4425,26 @@
   static FT_Bool
   SkipCode( EXEC_OP )
   {
-    CUR.IP += CUR.length;
+    exc->IP += exc->length;
 
-    if ( CUR.IP < CUR.codeSize )
+    if ( exc->IP < exc->codeSize )
     {
-      CUR.opcode = CUR.code[CUR.IP];
+      exc->opcode = exc->code[exc->IP];
 
-      CUR.length = opcode_length[CUR.opcode];
-      if ( CUR.length < 0 )
+      exc->length = opcode_length[exc->opcode];
+      if ( exc->length < 0 )
       {
-        if ( CUR.IP + 1 >= CUR.codeSize )
+        if ( exc->IP + 1 >= exc->codeSize )
           goto Fail_Overflow;
-        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
       }
 
-      if ( CUR.IP + CUR.length <= CUR.codeSize )
+      if ( exc->IP + exc->length <= exc->codeSize )
         return SUCCESS;
     }
 
   Fail_Overflow:
-    CUR.error = FT_THROW( Code_Overflow );
+    exc->error = FT_THROW( Code_Overflow );
     return FAILURE;
   }
 
@@ -4477,7 +4473,7 @@
       if ( SKIP_Code() == FAILURE )
         return;
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x58:      /* IF */
         nIfs++;
@@ -4517,7 +4513,7 @@
       if ( SKIP_Code() == FAILURE )
         return;
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x58:    /* IF */
         nIfs++;
@@ -4657,8 +4653,8 @@
     /* some font programs are broken enough to redefine functions! */
     /* We will then parse the current table.                       */
 
-    rec   = CUR.FDefs;
-    limit = rec + CUR.numFDefs;
+    rec   = exc->FDefs;
+    limit = rec + exc->numFDefs;
     n     = args[0];
 
     for ( ; rec < limit; rec++ )
@@ -4670,12 +4666,12 @@
     if ( rec == limit )
     {
       /* check that there is enough room for new functions */
-      if ( CUR.numFDefs >= CUR.maxFDefs )
+      if ( exc->numFDefs >= exc->maxFDefs )
       {
-        CUR.error = FT_THROW( Too_Many_Function_Defs );
+        exc->error = FT_THROW( Too_Many_Function_Defs );
         return;
       }
-      CUR.numFDefs++;
+      exc->numFDefs++;
     }
 
     /* Although FDEF takes unsigned 32-bit integer,  */
@@ -4682,19 +4678,19 @@
     /* func # must be within unsigned 16-bit integer */
     if ( n > 0xFFFFU )
     {
-      CUR.error = FT_THROW( Too_Many_Function_Defs );
+      exc->error = FT_THROW( Too_Many_Function_Defs );
       return;
     }
 
-    rec->range          = CUR.curRange;
+    rec->range          = exc->curRange;
     rec->opc            = (FT_UInt16)n;
-    rec->start          = CUR.IP + 1;
+    rec->start          = exc->IP + 1;
     rec->active         = TRUE;
     rec->inline_delta   = FALSE;
     rec->sph_fdef_flags = 0x0000;
 
-    if ( n > CUR.maxFunc )
-      CUR.maxFunc = (FT_UInt16)n;
+    if ( n > exc->maxFunc )
+      exc->maxFunc = (FT_UInt16)n;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* We don't know for sure these are typeman functions, */
@@ -4715,8 +4711,8 @@
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
-          if ( opcode_pointer[i] < opcode_size[i]                 &&
-               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+          if ( opcode_pointer[i] < opcode_size[i]                  &&
+               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
           {
             opcode_pointer[i] += 1;
 
@@ -4724,19 +4720,19 @@
             {
               FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
                           i, n,
-                          CUR.face->root.family_name,
-                          CUR.face->root.style_name ));
+                          exc->face->root.family_name,
+                          exc->face->root.style_name ));
 
               switch ( i )
               {
               case 0:
-                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_1;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
+                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_1;
+                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
                 break;
 
               case 1:
-                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_2;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
+                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_2;
+                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
                 break;
 
               case 2:
@@ -4744,8 +4740,8 @@
                 {
                   /* needs to be implemented still */
                 case 58:
-                  rec->sph_fdef_flags            |= SPH_FDEF_DIAGONAL_STROKE;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
+                  rec->sph_fdef_flags             |= SPH_FDEF_DIAGONAL_STROKE;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
                 }
                 break;
 
@@ -4753,15 +4749,15 @@
                 switch ( n )
                 {
                 case 0:
-                  rec->sph_fdef_flags            |= SPH_FDEF_VACUFORM_ROUND_1;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+                  rec->sph_fdef_flags             |= SPH_FDEF_VACUFORM_ROUND_1;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
                 }
                 break;
 
               case 4:
                 /* probably not necessary to detect anymore */
-                rec->sph_fdef_flags            |= SPH_FDEF_TTFAUTOHINT_1;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
+                rec->sph_fdef_flags             |= SPH_FDEF_TTFAUTOHINT_1;
+                exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
                 break;
 
               case 5:
@@ -4773,8 +4769,8 @@
                 case 4:
                 case 7:
                 case 8:
-                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_1;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
+                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_1;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
                 }
                 break;
 
@@ -4787,20 +4783,20 @@
                 case 4:
                 case 7:
                 case 8:
-                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_2;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
+                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_2;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
                 }
                 break;
 
                case 7:
-                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
                  break;
 
                case 8:
 #if 0
-                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 #endif
                  break;
               }
@@ -4813,22 +4809,22 @@
         }
 
         /* Set sph_compatibility_mode only when deltas are detected */
-        CUR.face->sph_compatibility_mode =
-          ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
-            ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
+        exc->face->sph_compatibility_mode =
+          ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
+            ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
       }
 
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x89:    /* IDEF */
       case 0x2C:    /* FDEF */
-        CUR.error = FT_THROW( Nested_DEFS );
+        exc->error = FT_THROW( Nested_DEFS );
         return;
 
       case 0x2D:   /* ENDF */
-        rec->end = CUR.IP;
+        rec->end = exc->IP;
         return;
       }
     }
@@ -4850,27 +4846,27 @@
 
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    CUR.sph_in_func_flags = 0x0000;
+    exc->sph_in_func_flags = 0x0000;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    if ( CUR.callTop <= 0 )     /* We encountered an ENDF without a call */
+    if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
     {
-      CUR.error = FT_THROW( ENDF_In_Exec_Stream );
+      exc->error = FT_THROW( ENDF_In_Exec_Stream );
       return;
     }
 
-    CUR.callTop--;
+    exc->callTop--;
 
-    pRec = &CUR.callStack[CUR.callTop];
+    pRec = &exc->callStack[exc->callTop];
 
     pRec->Cur_Count--;
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
 
     if ( pRec->Cur_Count > 0 )
     {
-      CUR.callTop++;
-      CUR.IP = pRec->Def->start;
+      exc->callTop++;
+      exc->IP = pRec->Def->start;
     }
     else
       /* Loop through the current function */
@@ -4904,7 +4900,7 @@
     /* first of all, check the index */
 
     F = args[0];
-    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
       goto Fail;
 
     /* Except for some old Apple fonts, all functions in a TrueType */
@@ -4911,20 +4907,20 @@
     /* font are defined in increasing order, starting from 0.  This */
     /* means that we normally have                                  */
     /*                                                              */
-    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
-    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*    exc->maxFunc+1 == exc->numFDefs                           */
+    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
     /*                                                              */
     /* If this isn't true, we need to look up the function table.   */
 
-    def = CUR.FDefs + F;
-    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+    def = exc->FDefs + F;
+    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
     {
       /* look up the FDefs table */
       TT_DefRecord*  limit;
 
 
-      def   = CUR.FDefs;
-      limit = def + CUR.numFDefs;
+      def   = exc->FDefs;
+      limit = def + exc->numFDefs;
 
       while ( def < limit && def->opc != F )
         def++;
@@ -4938,41 +4934,41 @@
       goto Fail;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                              &&
-         CUR.ignore_x_mode                                             &&
-         ( ( CUR.iup_called                                        &&
-             ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
-           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )       ) )
+    if ( SUBPIXEL_HINTING                                               &&
+         exc->ignore_x_mode                                             &&
+         ( ( exc->iup_called                                        &&
+             ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
+           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )        ) )
       goto Fail;
     else
-      CUR.sph_in_func_flags = def->sph_fdef_flags;
+      exc->sph_in_func_flags = def->sph_fdef_flags;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* check the call stack */
-    if ( CUR.callTop >= CUR.callSize )
+    if ( exc->callTop >= exc->callSize )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    pCrec = CUR.callStack + CUR.callTop;
+    pCrec = exc->callStack + exc->callTop;
 
-    pCrec->Caller_Range = CUR.curRange;
-    pCrec->Caller_IP    = CUR.IP + 1;
+    pCrec->Caller_Range = exc->curRange;
+    pCrec->Caller_IP    = exc->IP + 1;
     pCrec->Cur_Count    = 1;
     pCrec->Def          = def;
 
-    CUR.callTop++;
+    exc->callTop++;
 
     INS_Goto_CodeRange( def->range,
                         def->start );
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
 
     return;
 
   Fail:
-    CUR.error = FT_THROW( Invalid_Reference );
+    exc->error = FT_THROW( Invalid_Reference );
   }
 
 
@@ -4992,7 +4988,7 @@
 
     /* first of all, check the index */
     F = args[1];
-    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
       goto Fail;
 
     /* Except for some old Apple fonts, all functions in a TrueType */
@@ -4999,20 +4995,20 @@
     /* font are defined in increasing order, starting from 0.  This */
     /* means that we normally have                                  */
     /*                                                              */
-    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
-    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*    exc->maxFunc+1 == exc->numFDefs                           */
+    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
     /*                                                              */
     /* If this isn't true, we need to look up the function table.   */
 
-    def = CUR.FDefs + F;
-    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+    def = exc->FDefs + F;
+    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
     {
       /* look up the FDefs table */
       TT_DefRecord*  limit;
 
 
-      def   = CUR.FDefs;
-      limit = def + CUR.numFDefs;
+      def   = exc->FDefs;
+      limit = def + exc->numFDefs;
 
       while ( def < limit && def->opc != F )
         def++;
@@ -5027,40 +5023,40 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
+         exc->ignore_x_mode                                  &&
          ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
       goto Fail;
     else
-      CUR.sph_in_func_flags = def->sph_fdef_flags;
+      exc->sph_in_func_flags = def->sph_fdef_flags;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* check stack */
-    if ( CUR.callTop >= CUR.callSize )
+    if ( exc->callTop >= exc->callSize )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     if ( args[0] > 0 )
     {
-      pCrec = CUR.callStack + CUR.callTop;
+      pCrec = exc->callStack + exc->callTop;
 
-      pCrec->Caller_Range = CUR.curRange;
-      pCrec->Caller_IP    = CUR.IP + 1;
+      pCrec->Caller_Range = exc->curRange;
+      pCrec->Caller_IP    = exc->IP + 1;
       pCrec->Cur_Count    = (FT_Int)args[0];
       pCrec->Def          = def;
 
-      CUR.callTop++;
+      exc->callTop++;
 
       INS_Goto_CodeRange( def->range, def->start );
 
-      CUR.step_ins = FALSE;
+      exc->step_ins = FALSE;
     }
 
     return;
 
   Fail:
-    CUR.error = FT_THROW( Invalid_Reference );
+    exc->error = FT_THROW( Invalid_Reference );
   }
 
 
@@ -5079,8 +5075,8 @@
 
     /*  First of all, look for the same function in our table */
 
-    def   = CUR.IDefs;
-    limit = def + CUR.numIDefs;
+    def   = exc->IDefs;
+    limit = def + exc->numIDefs;
 
     for ( ; def < limit; def++ )
       if ( def->opc == (FT_ULong)args[0] )
@@ -5089,28 +5085,28 @@
     if ( def == limit )
     {
       /* check that there is enough room for a new instruction */
-      if ( CUR.numIDefs >= CUR.maxIDefs )
+      if ( exc->numIDefs >= exc->maxIDefs )
       {
-        CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+        exc->error = FT_THROW( Too_Many_Instruction_Defs );
         return;
       }
-      CUR.numIDefs++;
+      exc->numIDefs++;
     }
 
     /* opcode must be unsigned 8-bit integer */
     if ( 0 > args[0] || args[0] > 0x00FF )
     {
-      CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+      exc->error = FT_THROW( Too_Many_Instruction_Defs );
       return;
     }
 
     def->opc    = (FT_Byte)args[0];
-    def->start  = CUR.IP + 1;
-    def->range  = CUR.curRange;
+    def->start  = exc->IP + 1;
+    def->range  = exc->curRange;
     def->active = TRUE;
 
-    if ( (FT_ULong)args[0] > CUR.maxIns )
-      CUR.maxIns = (FT_Byte)args[0];
+    if ( (FT_ULong)args[0] > exc->maxIns )
+      exc->maxIns = (FT_Byte)args[0];
 
     /* Now skip the whole function definition. */
     /* We don't allow nested IDEFs & FDEFs.    */
@@ -5117,11 +5113,11 @@
 
     while ( SKIP_Code() == SUCCESS )
     {
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x89:   /* IDEF */
       case 0x2C:   /* FDEF */
-        CUR.error = FT_THROW( Nested_DEFS );
+        exc->error = FT_THROW( Nested_DEFS );
         return;
       case 0x2D:   /* ENDF */
         return;
@@ -5151,18 +5147,18 @@
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)CUR.code[CUR.IP + 1];
+    L = (FT_UShort)exc->code[exc->IP + 1];
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     for ( K = 1; K <= L; K++ )
-      args[K - 1] = CUR.code[CUR.IP + K + 1];
+      args[K - 1] = exc->code[exc->IP + K + 1];
 
-    CUR.new_top += L;
+    exc->new_top += L;
   }
 
 
@@ -5178,21 +5174,21 @@
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)CUR.code[CUR.IP + 1];
+    L = (FT_UShort)exc->code[exc->IP + 1];
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    CUR.IP += 2;
+    exc->IP += 2;
 
     for ( K = 0; K < L; K++ )
       args[K] = GET_ShortIns();
 
-    CUR.step_ins = FALSE;
-    CUR.new_top += L;
+    exc->step_ins = FALSE;
+    exc->new_top += L;
   }
 
 
@@ -5208,16 +5204,16 @@
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );
+    L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     for ( K = 1; K <= L; K++ )
-      args[K - 1] = CUR.code[CUR.IP + K];
+      args[K - 1] = exc->code[exc->IP + K];
   }
 
 
@@ -5233,20 +5229,20 @@
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );
+    L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    CUR.IP++;
+    exc->IP++;
 
     for ( K = 0; K < L; K++ )
       args[K] = GET_ShortIns();
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
   }
 
 
@@ -5277,18 +5273,18 @@
 
     L = (FT_ULong)args[0];
 
-    if ( BOUNDSL( L, CUR.zp2.n_points ) )
+    if ( BOUNDSL( L, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       R = 0;
     }
     else
     {
-      if ( CUR.opcode & 1 )
-        R = CUR_fast_dualproj( &CUR.zp2.org[L] );
+      if ( exc->opcode & 1 )
+        R = CUR_fast_dualproj( &exc->zp2.org[L] );
       else
-        R = CUR_fast_project( &CUR.zp2.cur[L] );
+        R = CUR_fast_project( &exc->zp2.cur[L] );
     }
 
     args[0] = R;
@@ -5314,21 +5310,21 @@
 
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( L, CUR.zp2.n_points ) )
+    if ( BOUNDS( L, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    K = CUR_fast_project( &CUR.zp2.cur[L] );
+    K = CUR_fast_project( &exc->zp2.cur[L] );
 
-    CUR_Func_move( &CUR.zp2, L, args[1] - K );
+    CUR_Func_move( &exc->zp2, L, args[1] - K );
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep2 == 0 )
-      CUR.zp2.org[L] = CUR.zp2.cur[L];
+    if ( exc->GS.gep2 == 0 )
+      exc->zp2.org[L] = exc->zp2.cur[L];
   }
 
 
@@ -5357,25 +5353,25 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( L, CUR.zp0.n_points ) ||
-         BOUNDS( K, CUR.zp1.n_points ) )
+    if ( BOUNDS( L, exc->zp0.n_points ) ||
+         BOUNDS( K, exc->zp1.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       D = 0;
     }
     else
     {
-      if ( CUR.opcode & 1 )
-        D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
+      if ( exc->opcode & 1 )
+        D = CUR_Func_project( exc->zp0.cur + L, exc->zp1.cur + K );
       else
       {
         /* XXX: UNDOCUMENTED: twilight zone special case */
 
-        if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+        if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
         {
-          FT_Vector*  vec1 = CUR.zp0.org + L;
-          FT_Vector*  vec2 = CUR.zp1.org + K;
+          FT_Vector*  vec1 = exc->zp0.org + L;
+          FT_Vector*  vec2 = exc->zp1.org + K;
 
 
           D = CUR_Func_dualproj( vec1, vec2 );
@@ -5382,15 +5378,15 @@
         }
         else
         {
-          FT_Vector*  vec1 = CUR.zp0.orus + L;
-          FT_Vector*  vec2 = CUR.zp1.orus + K;
+          FT_Vector*  vec1 = exc->zp0.orus + L;
+          FT_Vector*  vec2 = exc->zp1.orus + K;
 
 
-          if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+          if ( exc->metrics.x_scale == exc->metrics.y_scale )
           {
             /* this should be faster */
             D = CUR_Func_dualproj( vec1, vec2 );
-            D = FT_MulFix( D, CUR.metrics.x_scale );
+            D = FT_MulFix( D, exc->metrics.x_scale );
           }
           else
           {
@@ -5397,8 +5393,8 @@
             FT_Vector  vec;
 
 
-            vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
-            vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+            vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+            vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 
             D = CUR_fast_dualproj( &vec );
           }
@@ -5408,8 +5404,8 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING                       &&
-         CUR.ignore_x_mode && FT_ABS( D ) == 64 )
+    if ( SUBPIXEL_HINTING                        &&
+         exc->ignore_x_mode && FT_ABS( D ) == 64 )
       D += 1;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
@@ -5428,23 +5424,23 @@
   {
     FT_Long    A, B, C;
     FT_UShort  p1, p2;            /* was FT_Int in pas type ERROR */
-    FT_Int     aOpc = CUR.opcode;
+    FT_Int     aOpc = exc->opcode;
 
 
     p1 = (FT_UShort)args[1];
     p2 = (FT_UShort)args[0];
 
-    if ( BOUNDS( p2, CUR.zp1.n_points ) ||
-         BOUNDS( p1, CUR.zp2.n_points ) )
+    if ( BOUNDS( p2, exc->zp1.n_points ) ||
+         BOUNDS( p1, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     {
-      FT_Vector* v1 = CUR.zp1.org + p2;
-      FT_Vector* v2 = CUR.zp2.org + p1;
+      FT_Vector* v1 = exc->zp1.org + p2;
+      FT_Vector* v2 = exc->zp2.org + p1;
 
 
       A = v1->x - v2->x;
@@ -5469,11 +5465,11 @@
       A = -C;
     }
 
-    NORMalize( A, B, &CUR.GS.dualVector );
+    NORMalize( A, B, &exc->GS.dualVector );
 
     {
-      FT_Vector*  v1 = CUR.zp1.cur + p2;
-      FT_Vector*  v2 = CUR.zp2.cur + p1;
+      FT_Vector*  v1 = exc->zp1.cur + p2;
+      FT_Vector*  v2 = exc->zp2.cur + p1;
 
 
       A = v1->x - v2->x;
@@ -5493,7 +5489,7 @@
       A = -C;
     }
 
-    NORMalize( A, B, &CUR.GS.projVector );
+    NORMalize( A, B, &exc->GS.projVector );
 
     GUESS_VECTOR( freeVector );
 
@@ -5513,20 +5509,20 @@
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp0 = CUR.twilight;
+      exc->zp0 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp0 = CUR.pts;
+      exc->zp0 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep0 = (FT_UShort)args[0];
+    exc->GS.gep0 = (FT_UShort)args[0];
   }
 
 
@@ -5542,20 +5538,20 @@
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp1 = CUR.twilight;
+      exc->zp1 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp1 = CUR.pts;
+      exc->zp1 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep1 = (FT_UShort)args[0];
+    exc->GS.gep1 = (FT_UShort)args[0];
   }
 
 
@@ -5571,20 +5567,20 @@
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp2 = CUR.twilight;
+      exc->zp2 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp2 = CUR.pts;
+      exc->zp2 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep2 = (FT_UShort)args[0];
+    exc->GS.gep2 = (FT_UShort)args[0];
   }
 
 
@@ -5600,25 +5596,25 @@
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp0 = CUR.twilight;
+      exc->zp0 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp0 = CUR.pts;
+      exc->zp0 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.zp1 = CUR.zp0;
-    CUR.zp2 = CUR.zp0;
+    exc->zp1 = exc->zp0;
+    exc->zp2 = exc->zp0;
 
-    CUR.GS.gep0 = (FT_UShort)args[0];
-    CUR.GS.gep1 = (FT_UShort)args[0];
-    CUR.GS.gep2 = (FT_UShort)args[0];
+    exc->GS.gep0 = (FT_UShort)args[0];
+    exc->GS.gep1 = (FT_UShort)args[0];
+    exc->GS.gep2 = (FT_UShort)args[0];
   }
 
 
@@ -5639,8 +5635,8 @@
 
     if ( K < 1 || K > 2 )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
@@ -5647,8 +5643,8 @@
     if ( L != 0 )
         L = K;
 
-    CUR.GS.instruct_control = FT_BOOL(
-      ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
+    exc->GS.instruct_control = FT_BOOL(
+      ( (FT_Byte)exc->GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
   }
 
 
@@ -5669,32 +5665,32 @@
 
     if ( A == 0xFF )
     {
-      CUR.GS.scan_control = TRUE;
+      exc->GS.scan_control = TRUE;
       return;
     }
     else if ( A == 0 )
     {
-      CUR.GS.scan_control = FALSE;
+      exc->GS.scan_control = FALSE;
       return;
     }
 
-    if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
+      exc->GS.scan_control = FALSE;
 
-    if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
+      exc->GS.scan_control = FALSE;
 
-    if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
+      exc->GS.scan_control = FALSE;
   }
 
 
@@ -5708,7 +5704,7 @@
   Ins_SCANTYPE( INS_ARG )
   {
     if ( args[0] >= 0 )
-      CUR.GS.scan_type = (FT_Int)args[0];
+      exc->GS.scan_type = (FT_Int)args[0];
   }
 
 
@@ -5735,36 +5731,36 @@
     FT_UNUSED_ARG;
 
 
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Too_Few_Arguments );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Too_Few_Arguments );
       goto Fail;
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.pts.n_points ) )
+      if ( BOUNDS( point, exc->pts.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
-        CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;
+        exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -5783,16 +5779,16 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( K, CUR.pts.n_points ) ||
-         BOUNDS( L, CUR.pts.n_points ) )
+    if ( BOUNDS( K, exc->pts.n_points ) ||
+         BOUNDS( L, exc->pts.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     for ( I = L; I <= K; I++ )
-      CUR.pts.tags[I] |= FT_CURVE_TAG_ON;
+      exc->pts.tags[I] |= FT_CURVE_TAG_ON;
   }
 
 
@@ -5811,16 +5807,16 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( K, CUR.pts.n_points ) ||
-         BOUNDS( L, CUR.pts.n_points ) )
+    if ( BOUNDS( K, exc->pts.n_points ) ||
+         BOUNDS( L, exc->pts.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     for ( I = L; I <= K; I++ )
-      CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;
+      exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
   }
 
 
@@ -5835,21 +5831,21 @@
     FT_F26Dot6       d;
 
 
-    if ( CUR.opcode & 1 )
+    if ( exc->opcode & 1 )
     {
-      zp = CUR.zp0;
-      p  = CUR.GS.rp1;
+      zp = exc->zp0;
+      p  = exc->GS.rp1;
     }
     else
     {
-      zp = CUR.zp1;
-      p  = CUR.GS.rp2;
+      zp = exc->zp1;
+      p  = exc->GS.rp2;
     }
 
     if ( BOUNDS( p, zp.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       *refp = 0;
       return FAILURE;
     }
@@ -5860,9 +5856,9 @@
     d = CUR_Func_project( zp.cur + p, zp.org + p );
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
         *x = d;
         *y = 0;
@@ -5876,8 +5872,8 @@
     else
 #endif
     {
-      *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
-      *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
+      *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
+      *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
     }
 
     return SUCCESS;
@@ -5891,36 +5887,36 @@
                            FT_Bool     touch )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
-        CUR.zp2.cur[point].x += dx;
+        exc->zp2.cur[point].x += dx;
         if ( touch )
-          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
       }
       else
       {
-        CUR.zp2.cur[point].y += dy;
+        exc->zp2.cur[point].y += dy;
         if ( touch )
-          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
       }
       return;
     }
 #endif
 
-    if ( CUR.GS.freeVector.x != 0 )
+    if ( exc->GS.freeVector.x != 0 )
     {
-      CUR.zp2.cur[point].x += dx;
+      exc->zp2.cur[point].x += dx;
       if ( touch )
-        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
 
-    if ( CUR.GS.freeVector.y != 0 )
+    if ( exc->GS.freeVector.y != 0 )
     {
-      CUR.zp2.cur[point].y += dy;
+      exc->zp2.cur[point].y += dy;
       if ( touch )
-        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
   }
 
@@ -5944,10 +5940,10 @@
     FT_UNUSED_ARG;
 
 
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -5954,16 +5950,16 @@
     if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
       return;
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
-      point = (FT_UShort)CUR.stack[CUR.args];
+      exc->args--;
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
@@ -5970,19 +5966,19 @@
       else
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* doesn't follow Cleartype spec but produces better result */
-      if ( SUBPIXEL_HINTING  &&
-           CUR.ignore_x_mode )
+      if ( SUBPIXEL_HINTING   &&
+           exc->ignore_x_mode )
         MOVE_Zp2_Point( point, 0, dy, TRUE );
       else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
         MOVE_Zp2_Point( point, dx, dy, TRUE );
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6008,12 +6004,12 @@
 
 
     contour = (FT_UShort)args[0];
-    bounds  = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
+    bounds  = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
 
     if ( BOUNDS( contour, bounds ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
@@ -6023,19 +6019,19 @@
     if ( contour == 0 )
       start = 0;
     else
-      start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
-                           CUR.zp2.first_point );
+      start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
+                           exc->zp2.first_point );
 
     /* we use the number of points if in the twilight zone */
-    if ( CUR.GS.gep2 == 0 )
-      limit = CUR.zp2.n_points;
+    if ( exc->GS.gep2 == 0 )
+      limit = exc->zp2.n_points;
     else
-      limit = (FT_UShort)( CUR.zp2.contours[contour] -
-                           CUR.zp2.first_point + 1 );
+      limit = (FT_UShort)( exc->zp2.contours[contour] -
+                           exc->zp2.first_point + 1 );
 
     for ( i = start; i < limit; i++ )
     {
-      if ( zp.cur != CUR.zp2.cur || refp != i )
+      if ( zp.cur != exc->zp2.cur || refp != i )
         MOVE_Zp2_Point( i, dx, dy, TRUE );
     }
   }
@@ -6060,8 +6056,8 @@
 
     if ( BOUNDS( args[0], 2 ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
@@ -6072,10 +6068,10 @@
     /*      Twilight zone has no real contours, so use `n_points'. */
     /*      Normal zone's `n_points' includes phantoms, so must    */
     /*      use end of last contour.                               */
-    if ( CUR.GS.gep2 == 0 )
-      limit = (FT_UShort)CUR.zp2.n_points;
-    else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
-      limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
+    if ( exc->GS.gep2 == 0 )
+      limit = (FT_UShort)exc->zp2.n_points;
+    else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
+      limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
     else
       limit = 0;
 
@@ -6082,7 +6078,7 @@
     /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
     for ( i = 0; i < limit; i++ )
     {
-      if ( zp.cur != CUR.zp2.cur || refp != i )
+      if ( zp.cur != exc->zp2.cur || refp != i )
         MOVE_Zp2_Point( i, dx, dy, FALSE );
     }
   }
@@ -6104,17 +6100,17 @@
 #endif
 
 
-    if ( CUR.top < CUR.GS.loop + 1 )
+    if ( exc->top < exc->GS.loop + 1 )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
         dx = (FT_UInt32)args[0];
         dy = 0;
@@ -6128,21 +6124,21 @@
     else
 #endif
     {
-      dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
-      dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
+      dx = TT_MulFix14( (FT_UInt32)args[0], exc->GS.freeVector.x );
+      dy = TT_MulFix14( (FT_UInt32)args[0], exc->GS.freeVector.y );
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
@@ -6157,36 +6153,36 @@
         /*   - the glyph is specifically set to allow SHPIX moves          */
         /*   - the move is on a previously Y-touched point                 */
 
-        if ( SUBPIXEL_HINTING  &&
-             CUR.ignore_x_mode )
+        if ( SUBPIXEL_HINTING   &&
+             exc->ignore_x_mode )
         {
           /* save point for later comparison */
-          if ( CUR.GS.freeVector.y != 0 )
-            B1 = CUR.zp2.cur[point].y;
+          if ( exc->GS.freeVector.y != 0 )
+            B1 = exc->zp2.cur[point].y;
           else
-            B1 = CUR.zp2.cur[point].x;
+            B1 = exc->zp2.cur[point].x;
 
-          if ( !CUR.face->sph_compatibility_mode &&
-               CUR.GS.freeVector.y != 0          )
+          if ( !exc->face->sph_compatibility_mode &&
+               exc->GS.freeVector.y != 0          )
           {
             MOVE_Zp2_Point( point, dx, dy, TRUE );
 
             /* save new point */
-            if ( CUR.GS.freeVector.y != 0 )
+            if ( exc->GS.freeVector.y != 0 )
             {
-              B2 = CUR.zp2.cur[point].y;
+              B2 = exc->zp2.cur[point].y;
 
               /* reverse any disallowed moves */
-              if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-                   ( B1 & 63 ) != 0                                          &&
-                   ( B2 & 63 ) != 0                                          &&
-                    B1 != B2                                                 )
+              if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+                   ( B1 & 63 ) != 0                                           &&
+                   ( B2 & 63 ) != 0                                           &&
+                    B1 != B2                                                  )
                 MOVE_Zp2_Point( point, -dx, -dy, TRUE );
             }
           }
-          else if ( CUR.face->sph_compatibility_mode )
+          else if ( exc->face->sph_compatibility_mode )
           {
-            if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+            if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
             {
               dx = FT_PIX_ROUND( B1 + dx ) - B1;
               dy = FT_PIX_ROUND( B1 + dy ) - B1;
@@ -6193,21 +6189,21 @@
             }
 
             /* skip post-iup deltas */
-            if ( CUR.iup_called                                          &&
-                 ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
-                   ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
+            if ( exc->iup_called                                          &&
+                 ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
+                   ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
               goto Skip;
 
-            if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
-                  ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
-                    ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )   ||
-                    ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX )     )   )
+            if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
+                  ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                    ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )    ||
+                    ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX )      )  )
               MOVE_Zp2_Point( point, 0, dy, TRUE );
 
             /* save new point */
-            if ( CUR.GS.freeVector.y != 0 )
+            if ( exc->GS.freeVector.y != 0 )
             {
-              B2 = CUR.zp2.cur[point].y;
+              B2 = exc->zp2.cur[point].y;
 
               /* reverse any disallowed moves */
               if ( ( B1 & 63 ) == 0 &&
@@ -6216,7 +6212,7 @@
                 MOVE_Zp2_Point( point, 0, -dy, TRUE );
             }
           }
-          else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
+          else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
             MOVE_Zp2_Point( point, dx, dy, TRUE );
         }
         else
@@ -6231,12 +6227,12 @@
 
 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6258,11 +6254,11 @@
 
     if ( SUBPIXEL_HINTING )
     {
-      control_value_cutin = CUR.GS.control_value_cutin;
+      control_value_cutin = exc->GS.control_value_cutin;
 
-      if ( CUR.ignore_x_mode                                 &&
-           CUR.GS.freeVector.x != 0                          &&
-           !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+      if ( exc->ignore_x_mode                                 &&
+           exc->GS.freeVector.x != 0                          &&
+           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
         control_value_cutin = 0;
     }
 
@@ -6270,42 +6266,42 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep1 == 0 )
     {
-      CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
-      CUR_Func_move_orig( &CUR.zp1, point, args[1] );
-      CUR.zp1.cur[point] = CUR.zp1.org[point];
+      exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
+      CUR_Func_move_orig( &exc->zp1, point, args[1] );
+      exc->zp1.cur[point] = exc->zp1.org[point];
     }
 
-    distance = CUR_Func_project( CUR.zp1.cur + point,
-                                 CUR.zp0.cur + CUR.GS.rp0 );
+    distance = CUR_Func_project( exc->zp1.cur + point,
+                                 exc->zp0.cur + exc->GS.rp0 );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* subpixel hinting - make MSIRP respect CVT cut-in; */
     if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
-         CUR.GS.freeVector.x != 0                            &&
+         exc->ignore_x_mode                                  &&
+         exc->GS.freeVector.x != 0                           &&
          FT_ABS( distance - args[1] ) >= control_value_cutin )
       distance = args[1];
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    CUR_Func_move( &CUR.zp1, point, args[1] - distance );
+    CUR_Func_move( &exc->zp1, point, args[1] - distance );
 
-    CUR.GS.rp1 = CUR.GS.rp0;
-    CUR.GS.rp2 = point;
+    exc->GS.rp1 = exc->GS.rp0;
+    exc->GS.rp2 = point;
 
-    if ( ( CUR.opcode & 1 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 1 ) != 0 )
+      exc->GS.rp0 = point;
   }
 
 
@@ -6325,36 +6321,36 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    if ( BOUNDS( point, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    if ( ( CUR.opcode & 1 ) != 0 )
+    if ( ( exc->opcode & 1 ) != 0 )
     {
-      cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+      cur_dist = CUR_fast_project( &exc->zp0.cur[point] );
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
         distance = ROUND_None(
                      cur_dist,
-                     CUR.tt_metrics.compensations[0] ) - cur_dist;
+                     exc->tt_metrics.compensations[0] ) - cur_dist;
       else
 #endif
         distance = CUR_Func_round(
                      cur_dist,
-                     CUR.tt_metrics.compensations[0] ) - cur_dist;
+                     exc->tt_metrics.compensations[0] ) - cur_dist;
     }
     else
       distance = 0;
 
-    CUR_Func_move( &CUR.zp0, point, distance );
+    CUR_Func_move( &exc->zp0, point, distance );
 
-    CUR.GS.rp0 = point;
-    CUR.GS.rp1 = point;
+    exc->GS.rp0 = point;
+    exc->GS.rp1 = point;
   }
 
 
@@ -6374,24 +6370,24 @@
     FT_F26Dot6  control_value_cutin;
 
 
-    control_value_cutin = CUR.GS.control_value_cutin;
+    control_value_cutin = exc->GS.control_value_cutin;
     cvtEntry            = (FT_ULong)args[1];
     point               = (FT_UShort)args[0];
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         CUR.GS.freeVector.y == 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         exc->ignore_x_mode                                 &&
+         exc->GS.freeVector.x != 0                          &&
+         exc->GS.freeVector.y == 0                          &&
+         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       control_value_cutin = 0;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    if ( BOUNDS( point,     CUR.zp0.n_points ) ||
-         BOUNDSL( cvtEntry, CUR.cvtSize )      )
+    if ( BOUNDS( point,     exc->zp0.n_points ) ||
+         BOUNDSL( cvtEntry, exc->cvtSize )      )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -6417,54 +6413,54 @@
 
     distance = CUR_Func_read_cvt( cvtEntry );
 
-    if ( CUR.GS.gep0 == 0 )   /* If in twilight zone */
+    if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
       /* Determined via experimentation and may be incorrect...         */
-      if ( !SUBPIXEL_HINTING                     ||
-           ( !CUR.ignore_x_mode                ||
-             !CUR.face->sph_compatibility_mode ) )
+      if ( !SUBPIXEL_HINTING                      ||
+           ( !exc->ignore_x_mode                ||
+             !exc->face->sph_compatibility_mode ) )
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
-                                            CUR.GS.freeVector.x );
-      CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
-                                          CUR.GS.freeVector.y ),
-      CUR.zp0.cur[point]   = CUR.zp0.org[point];
+        exc->zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
+                                             exc->GS.freeVector.x );
+      exc->zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
+                                           exc->GS.freeVector.y ),
+      exc->zp0.cur[point]   = exc->zp0.org[point];
     }
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                              &&
-         CUR.ignore_x_mode                             &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
-         distance > 0                                  &&
-         CUR.GS.freeVector.y != 0                      )
+    if ( SUBPIXEL_HINTING                               &&
+         exc->ignore_x_mode                             &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
+         distance > 0                                   &&
+         exc->GS.freeVector.y != 0                      )
       distance = 0;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+    org_dist = CUR_fast_project( &exc->zp0.cur[point] );
 
-    if ( ( CUR.opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
+    if ( ( exc->opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
     {
       if ( FT_ABS( distance - org_dist ) > control_value_cutin )
         distance = org_dist;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
         distance = ROUND_None( distance,
-                               CUR.tt_metrics.compensations[0] );
+                               exc->tt_metrics.compensations[0] );
       else
 #endif
         distance = CUR_Func_round( distance,
-                                   CUR.tt_metrics.compensations[0] );
+                                   exc->tt_metrics.compensations[0] );
     }
 
-    CUR_Func_move( &CUR.zp0, point, distance - org_dist );
+    CUR_Func_move( &exc->zp0, point, distance - org_dist );
 
   Fail:
-    CUR.GS.rp0 = point;
-    CUR.GS.rp1 = point;
+    exc->GS.rp0 = point;
+    exc->GS.rp1 = point;
   }
 
 
@@ -6481,23 +6477,23 @@
     FT_F26Dot6  org_dist, distance, minimum_distance;
 
 
-    minimum_distance = CUR.GS.minimum_distance;
+    minimum_distance = exc->GS.minimum_distance;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         exc->ignore_x_mode                                 &&
+         exc->GS.freeVector.x != 0                          &&
+         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       minimum_distance = 0;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -6506,10 +6502,10 @@
 
     /* XXX: UNDOCUMENTED: twilight zone special case */
 
-    if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
     {
-      FT_Vector*  vec1 = &CUR.zp1.org[point];
-      FT_Vector*  vec2 = &CUR.zp0.org[CUR.GS.rp0];
+      FT_Vector*  vec1 = &exc->zp1.org[point];
+      FT_Vector*  vec2 = &exc->zp0.org[exc->GS.rp0];
 
 
       org_dist = CUR_Func_dualproj( vec1, vec2 );
@@ -6516,15 +6512,15 @@
     }
     else
     {
-      FT_Vector*  vec1 = &CUR.zp1.orus[point];
-      FT_Vector*  vec2 = &CUR.zp0.orus[CUR.GS.rp0];
+      FT_Vector*  vec1 = &exc->zp1.orus[point];
+      FT_Vector*  vec2 = &exc->zp0.orus[exc->GS.rp0];
 
 
-      if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+      if ( exc->metrics.x_scale == exc->metrics.y_scale )
       {
         /* this should be faster */
         org_dist = CUR_Func_dualproj( vec1, vec2 );
-        org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
+        org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
       }
       else
       {
@@ -6531,8 +6527,8 @@
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
-        vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+        vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+        vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 
         org_dist = CUR_fast_dualproj( &vec );
       }
@@ -6540,40 +6536,40 @@
 
     /* single width cut-in test */
 
-    if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <
-         CUR.GS.single_width_cutin )
+    if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
+         exc->GS.single_width_cutin )
     {
       if ( org_dist >= 0 )
-        org_dist = CUR.GS.single_width_value;
+        org_dist = exc->GS.single_width_value;
       else
-        org_dist = -CUR.GS.single_width_value;
+        org_dist = -exc->GS.single_width_value;
     }
 
     /* round flag */
 
-    if ( ( CUR.opcode & 4 ) != 0 )
+    if ( ( exc->opcode & 4 ) != 0 )
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
         distance = ROUND_None(
                      org_dist,
-                     CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                     exc->tt_metrics.compensations[exc->opcode & 3] );
       else
 #endif
       distance = CUR_Func_round(
                    org_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
     }
     else
       distance = ROUND_None(
                    org_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
 
     /* minimum distance flag */
 
-    if ( ( CUR.opcode & 8 ) != 0 )
+    if ( ( exc->opcode & 8 ) != 0 )
     {
       if ( org_dist >= 0 )
       {
@@ -6589,17 +6585,17 @@
 
     /* now move the point */
 
-    org_dist = CUR_Func_project( CUR.zp1.cur + point,
-                                 CUR.zp0.cur + CUR.GS.rp0 );
+    org_dist = CUR_Func_project( exc->zp1.cur + point,
+                                 exc->zp0.cur + exc->GS.rp0 );
 
-    CUR_Func_move( &CUR.zp1, point, distance - org_dist );
+    CUR_Func_move( &exc->zp1, point, distance - org_dist );
 
   Fail:
-    CUR.GS.rp1 = CUR.GS.rp0;
-    CUR.GS.rp2 = point;
+    exc->GS.rp1 = exc->GS.rp0;
+    exc->GS.rp2 = point;
 
-    if ( ( CUR.opcode & 16 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 16 ) != 0 )
+      exc->GS.rp0 = point;
   }
 
 
@@ -6628,27 +6624,27 @@
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
 
-    minimum_distance    = CUR.GS.minimum_distance;
-    control_value_cutin = CUR.GS.control_value_cutin;
+    minimum_distance    = exc->GS.minimum_distance;
+    control_value_cutin = exc->GS.control_value_cutin;
     point               = (FT_UShort)args[0];
     cvtEntry            = (FT_ULong)( args[1] + 1 );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         exc->ignore_x_mode                                 &&
+         exc->GS.freeVector.x != 0                          &&
+         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       control_value_cutin = minimum_distance = 0;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDSL( cvtEntry,  CUR.cvtSize + 1 )  ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDSL( cvtEntry,   exc->cvtSize + 1 )  ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -6659,36 +6655,36 @@
 
     /* single width test */
 
-    if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
-         CUR.GS.single_width_cutin )
+    if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
+         exc->GS.single_width_cutin )
     {
       if ( cvt_dist >= 0 )
-        cvt_dist =  CUR.GS.single_width_value;
+        cvt_dist =  exc->GS.single_width_value;
       else
-        cvt_dist = -CUR.GS.single_width_value;
+        cvt_dist = -exc->GS.single_width_value;
     }
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep1 == 0 )
     {
-      CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
-                             TT_MulFix14( (FT_UInt32)cvt_dist,
-                                          CUR.GS.freeVector.x );
-      CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
-                             TT_MulFix14( (FT_UInt32)cvt_dist,
-                                          CUR.GS.freeVector.y );
-      CUR.zp1.cur[point]   = CUR.zp1.org[point];
+      exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
+                              TT_MulFix14( (FT_UInt32)cvt_dist,
+                                           exc->GS.freeVector.x );
+      exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
+                              TT_MulFix14( (FT_UInt32)cvt_dist,
+                                           exc->GS.freeVector.y );
+      exc->zp1.cur[point]   = exc->zp1.org[point];
     }
 
-    org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
-                                  &CUR.zp0.org[CUR.GS.rp0] );
-    cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
-                                  &CUR.zp0.cur[CUR.GS.rp0] );
+    org_dist = CUR_Func_dualproj( &exc->zp1.org[point],
+                                  &exc->zp0.org[exc->GS.rp0] );
+    cur_dist = CUR_Func_project ( &exc->zp1.cur[point],
+                                  &exc->zp0.cur[exc->GS.rp0] );
 
     /* auto-flip test */
 
-    if ( CUR.GS.auto_flip )
+    if ( exc->GS.auto_flip )
     {
       if ( ( org_dist ^ cvt_dist ) < 0 )
         cvt_dist = -cvt_dist;
@@ -6695,10 +6691,10 @@
     }
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                         &&
-         CUR.ignore_x_mode                                        &&
-         CUR.GS.freeVector.y != 0                                 &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
+    if ( SUBPIXEL_HINTING                                          &&
+         exc->ignore_x_mode                                        &&
+         exc->GS.freeVector.y != 0                                 &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
     {
       if ( cur_dist < -64 )
         cvt_dist -= 16;
@@ -6709,12 +6705,12 @@
 
     /* control value cut-in and round */
 
-    if ( ( CUR.opcode & 4 ) != 0 )
+    if ( ( exc->opcode & 4 ) != 0 )
     {
       /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */
       /*      refer to the same zone.                                  */
 
-      if ( CUR.GS.gep0 == CUR.GS.gep1 )
+      if ( exc->GS.gep0 == exc->GS.gep1 )
       {
         /* XXX: According to Greg Hitchcock, the following wording is */
         /*      the right one:                                        */
@@ -6734,7 +6730,7 @@
 
       distance = CUR_Func_round(
                    cvt_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
     }
     else
     {
@@ -6741,9 +6737,9 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* do cvt cut-in always in MIRP for sph */
-      if ( SUBPIXEL_HINTING           &&
-           CUR.ignore_x_mode          &&
-           CUR.GS.gep0 == CUR.GS.gep1 )
+      if ( SUBPIXEL_HINTING             &&
+           exc->ignore_x_mode           &&
+           exc->GS.gep0 == exc->GS.gep1 )
       {
         if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
           cvt_dist = org_dist;
@@ -6752,12 +6748,12 @@
 
       distance = ROUND_None(
                    cvt_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
     }
 
     /* minimum distance test */
 
-    if ( ( CUR.opcode & 8 ) != 0 )
+    if ( ( exc->opcode & 8 ) != 0 )
     {
       if ( org_dist >= 0 )
       {
@@ -6774,59 +6770,59 @@
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING )
     {
-      B1 = CUR.zp1.cur[point].y;
+      B1 = exc->zp1.cur[point].y;
 
       /* Round moves if necessary */
-      if ( CUR.ignore_x_mode                                          &&
-           CUR.GS.freeVector.y != 0                                   &&
-           ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+      if ( exc->ignore_x_mode                                          &&
+           exc->GS.freeVector.y != 0                                   &&
+           ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
         distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
 
-      if ( CUR.ignore_x_mode                                      &&
-           CUR.GS.freeVector.y != 0                               &&
-           ( CUR.opcode & 16 ) == 0                               &&
-           ( CUR.opcode & 8 ) == 0                                &&
-           ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
+      if ( exc->ignore_x_mode                                      &&
+           exc->GS.freeVector.y != 0                               &&
+           ( exc->opcode & 16 ) == 0                               &&
+           ( exc->opcode & 8 ) == 0                                &&
+           ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
         distance += 64;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+    CUR_Func_move( &exc->zp1, point, distance - cur_dist );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING )
     {
-      B2 = CUR.zp1.cur[point].y;
+      B2 = exc->zp1.cur[point].y;
 
       /* Reverse move if necessary */
-      if ( CUR.ignore_x_mode )
+      if ( exc->ignore_x_mode )
       {
-        if ( CUR.face->sph_compatibility_mode                          &&
-             CUR.GS.freeVector.y != 0                                  &&
-             ( B1 & 63 ) == 0                                          &&
-             ( B2 & 63 ) != 0                                          )
+        if ( exc->face->sph_compatibility_mode &&
+             exc->GS.freeVector.y != 0         &&
+             ( B1 & 63 ) == 0                  &&
+             ( B2 & 63 ) != 0                  )
           reverse_move = TRUE;
 
-        if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-             CUR.GS.freeVector.y != 0                                  &&
-             ( B2 & 63 ) != 0                                          &&
-             ( B1 & 63 ) != 0                                          )
+        if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+             exc->GS.freeVector.y != 0                                  &&
+             ( B2 & 63 ) != 0                                           &&
+             ( B1 & 63 ) != 0                                           )
           reverse_move = TRUE;
       }
 
       if ( reverse_move )
-        CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
+        CUR_Func_move( &exc->zp1, point, -( distance - cur_dist ) );
     }
 
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
   Fail:
-    CUR.GS.rp1 = CUR.GS.rp0;
+    exc->GS.rp1 = exc->GS.rp0;
 
-    if ( ( CUR.opcode & 16 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 16 ) != 0 )
+      exc->GS.rp0 = point;
 
-    CUR.GS.rp2 = point;
+    exc->GS.rp2 = point;
   }
 
 
@@ -6846,52 +6842,52 @@
 
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                         &&
-         CUR.ignore_x_mode                                        &&
-         CUR.iup_called                                           &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
+    if ( SUBPIXEL_HINTING                                          &&
+         exc->ignore_x_mode                                        &&
+         exc->iup_called                                           &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
     {
-      CUR.error = FT_THROW( Invalid_Reference );
+      exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    if ( CUR.top < CUR.GS.loop ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( exc->top < exc->GS.loop ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp1.n_points ) )
+      if ( BOUNDS( point, exc->zp1.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
       {
-        distance = CUR_Func_project( CUR.zp1.cur + point,
-                                     CUR.zp0.cur + CUR.GS.rp0 );
+        distance = CUR_Func_project( exc->zp1.cur + point,
+                                     exc->zp0.cur + exc->GS.rp0 );
 
-        CUR_Func_move( &CUR.zp1, point, -distance );
+        CUR_Func_move( &exc->zp1, point, -distance );
       }
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6926,29 +6922,29 @@
     b0 = (FT_UShort)args[3];
     b1 = (FT_UShort)args[4];
 
-    if ( BOUNDS( b0, CUR.zp0.n_points )  ||
-         BOUNDS( b1, CUR.zp0.n_points )  ||
-         BOUNDS( a0, CUR.zp1.n_points )  ||
-         BOUNDS( a1, CUR.zp1.n_points )  ||
-         BOUNDS( point, CUR.zp2.n_points ) )
+    if ( BOUNDS( b0,    exc->zp0.n_points ) ||
+         BOUNDS( b1,    exc->zp0.n_points ) ||
+         BOUNDS( a0,    exc->zp1.n_points ) ||
+         BOUNDS( a1,    exc->zp1.n_points ) ||
+         BOUNDS( point, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     /* Cramer's rule */
 
-    dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
-    dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
+    dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
+    dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
 
-    dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
-    day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
+    dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
+    day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
 
-    dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
-    dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
+    dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
+    dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
 
-    CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
+    exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
 
     discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
                    FT_MulDiv( day, dbx, 0x40 );
@@ -6970,21 +6966,21 @@
       R.x = FT_MulDiv( val, dax, discriminant );
       R.y = FT_MulDiv( val, day, discriminant );
 
-      CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
-      CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
+      exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
+      exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
     }
     else
     {
       /* else, take the middle of the middles of A and B */
 
-      CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
-                               CUR.zp1.cur[a1].x +
-                               CUR.zp0.cur[b0].x +
-                               CUR.zp0.cur[b1].x ) / 4;
-      CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
-                               CUR.zp1.cur[a1].y +
-                               CUR.zp0.cur[b0].y +
-                               CUR.zp0.cur[b1].y ) / 4;
+      exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
+                                exc->zp1.cur[a1].x +
+                                exc->zp0.cur[b0].x +
+                                exc->zp0.cur[b1].x ) / 4;
+      exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
+                                exc->zp1.cur[a1].y +
+                                exc->zp0.cur[b0].y +
+                                exc->zp0.cur[b1].y ) / 4;
     }
   }
 
@@ -7005,19 +7001,19 @@
     p1 = (FT_UShort)args[0];
     p2 = (FT_UShort)args[1];
 
-    if ( BOUNDS( p1, CUR.zp1.n_points ) ||
-         BOUNDS( p2, CUR.zp0.n_points ) )
+    if ( BOUNDS( p1, exc->zp1.n_points ) ||
+         BOUNDS( p2, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    distance = CUR_Func_project( CUR.zp0.cur + p2,
-                                 CUR.zp1.cur + p1 ) / 2;
+    distance = CUR_Func_project( exc->zp0.cur + p2,
+                                 exc->zp1.cur + p1 ) / 2;
 
-    CUR_Func_move( &CUR.zp1, p1, distance );
-    CUR_Func_move( &CUR.zp0, p2, -distance );
+    CUR_Func_move( &exc->zp1, p1, distance );
+    CUR_Func_move( &exc->zp0, p2, -distance );
   }
 
 
@@ -7041,40 +7037,40 @@
     FT_UNUSED_ARG;
 
 
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
     /*
      * We need to deal in a special way with the twilight zone.
-     * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
+     * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
      * for every n.
      */
-    twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
+    twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
 
-    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
+    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
     if ( twilight )
-      orus_base = &CUR.zp0.org[CUR.GS.rp1];
+      orus_base = &exc->zp0.org[exc->GS.rp1];
     else
-      orus_base = &CUR.zp0.orus[CUR.GS.rp1];
+      orus_base = &exc->zp0.orus[exc->GS.rp1];
 
-    cur_base = &CUR.zp0.cur[CUR.GS.rp1];
+    cur_base = &exc->zp0.cur[exc->GS.rp1];
 
     /* XXX: There are some glyphs in some braindead but popular */
     /*      fonts out there (e.g. [aeu]grave in monotype.ttf)   */
     /*      calling IP[] with bad values of rp[12].             */
     /*      Do something sane when this odd thing happens.      */
-    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
-         BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
+    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
+         BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
     {
       old_range = 0;
       cur_range = 0;
@@ -7082,10 +7078,10 @@
     else
     {
       if ( twilight )
-        old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
+        old_range = CUR_Func_dualproj( &exc->zp1.org[exc->GS.rp2],
                                        orus_base );
-      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
-        old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
+      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+        old_range = CUR_Func_dualproj( &exc->zp1.orus[exc->GS.rp2],
                                        orus_base );
       else
       {
@@ -7092,29 +7088,29 @@
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
-                           CUR.metrics.x_scale );
-        vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
-                           CUR.metrics.y_scale );
+        vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
+                           exc->metrics.x_scale );
+        vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
+                           exc->metrics.y_scale );
 
         old_range = CUR_fast_dualproj( &vec );
       }
 
-      cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
+      cur_range = CUR_Func_project ( &exc->zp1.cur[exc->GS.rp2], cur_base );
     }
 
-    for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
+    for ( ; exc->GS.loop > 0; --exc->GS.loop )
     {
-      FT_UInt     point = (FT_UInt)CUR.stack[--CUR.args];
+      FT_UInt     point = (FT_UInt)exc->stack[--exc->args];
       FT_F26Dot6  org_dist, cur_dist, new_dist;
 
 
       /* check point bounds */
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
         continue;
@@ -7121,23 +7117,23 @@
       }
 
       if ( twilight )
-        org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
-      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
-        org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
+        org_dist = CUR_Func_dualproj( &exc->zp2.org[point], orus_base );
+      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+        org_dist = CUR_Func_dualproj( &exc->zp2.orus[point], orus_base );
       else
       {
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
-                           CUR.metrics.x_scale );
-        vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
-                           CUR.metrics.y_scale );
+        vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
+                           exc->metrics.x_scale );
+        vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
+                           exc->metrics.y_scale );
 
         org_dist = CUR_fast_dualproj( &vec );
       }
 
-      cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
+      cur_dist = CUR_Func_project( &exc->zp2.cur[point], cur_base );
 
       if ( org_dist )
       {
@@ -7167,12 +7163,12 @@
       else
         new_dist = 0;
 
-      CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
+      CUR_Func_move( &exc->zp2, (FT_UShort)point, new_dist - cur_dist );
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -7191,22 +7187,22 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    if ( BOUNDS( point, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     mask = 0xFF;
 
-    if ( CUR.GS.freeVector.x != 0 )
+    if ( exc->GS.freeVector.x != 0 )
       mask &= ~FT_CURVE_TAG_TOUCH_X;
 
-    if ( CUR.GS.freeVector.y != 0 )
+    if ( exc->GS.freeVector.y != 0 )
       mask &= ~FT_CURVE_TAG_TOUCH_Y;
 
-    CUR.zp0.tags[point] &= mask;
+    exc->zp0.tags[point] &= mask;
   }
 
 
@@ -7361,34 +7357,34 @@
 
 
     /* ignore empty outlines */
-    if ( CUR.pts.n_contours == 0 )
+    if ( exc->pts.n_contours == 0 )
       return;
 
-    if ( CUR.opcode & 1 )
+    if ( exc->opcode & 1 )
     {
       mask   = FT_CURVE_TAG_TOUCH_X;
-      V.orgs = CUR.pts.org;
-      V.curs = CUR.pts.cur;
-      V.orus = CUR.pts.orus;
+      V.orgs = exc->pts.org;
+      V.curs = exc->pts.cur;
+      V.orus = exc->pts.orus;
     }
     else
     {
       mask   = FT_CURVE_TAG_TOUCH_Y;
-      V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );
-      V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
-      V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
+      V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
+      V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
+      V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
     }
-    V.max_points = CUR.pts.n_points;
+    V.max_points = exc->pts.n_points;
 
     contour = 0;
     point   = 0;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING  &&
-         CUR.ignore_x_mode )
+    if ( SUBPIXEL_HINTING   &&
+         exc->ignore_x_mode )
     {
-      CUR.iup_called = TRUE;
-      if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
+      exc->iup_called = TRUE;
+      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
         return;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -7395,13 +7391,13 @@
 
     do
     {
-      end_point   = CUR.pts.contours[contour] - CUR.pts.first_point;
+      end_point   = exc->pts.contours[contour] - exc->pts.first_point;
       first_point = point;
 
-      if ( BOUNDS ( end_point, CUR.pts.n_points ) )
-        end_point = CUR.pts.n_points - 1;
+      if ( BOUNDS( end_point, exc->pts.n_points ) )
+        end_point = exc->pts.n_points - 1;
 
-      while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
+      while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
         point++;
 
       if ( point <= end_point )
@@ -7413,7 +7409,7 @@
 
         while ( point <= end_point )
         {
-          if ( ( CUR.pts.tags[point] & mask ) != 0 )
+          if ( ( exc->pts.tags[point] & mask ) != 0 )
           {
             _iup_worker_interpolate( &V,
                                      cur_touched + 1,
@@ -7445,7 +7441,7 @@
         }
       }
       contour++;
-    } while ( contour < CUR.pts.n_contours );
+    } while ( contour < exc->pts.n_contours );
   }
 
 
@@ -7466,10 +7462,10 @@
     FT_UShort  B1, B2;
 
 
-    if ( SUBPIXEL_HINTING                                        &&
-         CUR.ignore_x_mode                                       &&
-         CUR.iup_called                                          &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
+    if ( SUBPIXEL_HINTING                                         &&
+         exc->ignore_x_mode                                       &&
+         exc->iup_called                                          &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
       goto Fail;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
@@ -7476,20 +7472,20 @@
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
     /* Delta hinting is covered by US Patent 5159668. */
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
       FT_Long  n = args[0] * 2;
 
 
-      if ( CUR.args < n )
+      if ( exc->args < n )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        n = CUR.args;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        n = exc->args;
       }
 
-      CUR.args -= n;
-      CUR.new_top = CUR.args;
+      exc->args -= n;
+      exc->new_top = exc->args;
       return;
     }
 #endif
@@ -7500,18 +7496,18 @@
 
     for ( k = 1; k <= nump; k++ )
     {
-      if ( CUR.args < 2 )
+      if ( exc->args < 2 )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        CUR.args = 0;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        exc->args = 0;
         goto Fail;
       }
 
-      CUR.args -= 2;
+      exc->args -= 2;
 
-      A = (FT_UShort)CUR.stack[CUR.args + 1];
-      B = CUR.stack[CUR.args];
+      A = (FT_UShort)exc->stack[exc->args + 1];
+      B = exc->stack[exc->args];
 
       /* XXX: Because some popular fonts contain some invalid DeltaP */
       /*      instructions, we simply ignore them when the stacked   */
@@ -7519,11 +7515,11 @@
       /*      error.  As a delta instruction doesn't change a glyph  */
       /*      in great ways, this shouldn't be a problem.            */
 
-      if ( !BOUNDS( A, CUR.zp0.n_points ) )
+      if ( !BOUNDS( A, exc->zp0.n_points ) )
       {
         C = ( (FT_ULong)B & 0xF0 ) >> 4;
 
-        switch ( CUR.opcode )
+        switch ( exc->opcode )
         {
         case 0x5D:
           break;
@@ -7537,7 +7533,7 @@
           break;
         }
 
-        C += CUR.GS.delta_base;
+        C += exc->GS.delta_base;
 
         if ( P == C )
         {
@@ -7544,7 +7540,7 @@
           B = ( (FT_ULong)B & 0xF ) - 8;
           if ( B >= 0 )
             B++;
-          B *= 1L << ( 6 - CUR.GS.delta_shift );
+          B *= 1L << ( 6 - exc->GS.delta_shift );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
@@ -7558,65 +7554,65 @@
              *  - glyph is composite and freedom vector is not in subpixel
              *    direction.
              */
-            if ( !CUR.ignore_x_mode                                   ||
-                 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
-                 ( CUR.is_composite && CUR.GS.freeVector.y != 0 )     )
-              CUR_Func_move( &CUR.zp0, A, B );
+            if ( !exc->ignore_x_mode                                   ||
+                 ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
+                 ( exc->is_composite && exc->GS.freeVector.y != 0 )    )
+              CUR_Func_move( &exc->zp0, A, B );
 
             /* Otherwise, apply subpixel hinting and compatibility mode */
             /* rules, always skipping deltas in subpixel direction.     */
-            else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
+            else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
             {
               /* save the y value of the point now; compare after move */
-              B1 = (FT_UShort)CUR.zp0.cur[A].y;
+              B1 = (FT_UShort)exc->zp0.cur[A].y;
 
               /* Standard subpixel hinting: Allow y move for y-touched */
               /* points.  This messes up DejaVu ...                    */
-              if ( !CUR.face->sph_compatibility_mode          &&
-                   ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                CUR_Func_move( &CUR.zp0, A, B );
+              if ( !exc->face->sph_compatibility_mode          &&
+                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+                CUR_Func_move( &exc->zp0, A, B );
 
               /* compatibility mode */
-              else if ( CUR.face->sph_compatibility_mode                      &&
-                        !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
+              else if ( exc->face->sph_compatibility_mode                        &&
+                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
               {
-                if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+                if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
                   B = FT_PIX_ROUND( B1 + B ) - B1;
 
                 /* Allow delta move if using sph_compatibility_mode,   */
                 /* IUP has not been called, and point is touched on Y. */
-                if ( !CUR.iup_called                            &&
-                     ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                  CUR_Func_move( &CUR.zp0, A, B );
+                if ( !exc->iup_called                            &&
+                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+                  CUR_Func_move( &exc->zp0, A, B );
               }
 
-              B2 = (FT_UShort)CUR.zp0.cur[A].y;
+              B2 = (FT_UShort)exc->zp0.cur[A].y;
 
               /* Reverse this move if it results in a disallowed move */
-              if ( CUR.GS.freeVector.y != 0                           &&
-                   ( ( CUR.face->sph_compatibility_mode           &&
+              if ( exc->GS.freeVector.y != 0                          &&
+                   ( ( exc->face->sph_compatibility_mode          &&
                        ( B1 & 63 ) == 0                           &&
                        ( B2 & 63 ) != 0                           ) ||
-                     ( ( CUR.sph_tweak_flags                    &
+                     ( ( exc->sph_tweak_flags                   &
                          SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
                        ( B1 & 63 ) != 0                           &&
                        ( B2 & 63 ) != 0                           ) ) )
-                CUR_Func_move( &CUR.zp0, A, -B );
+                CUR_Func_move( &exc->zp0, A, -B );
             }
           }
           else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-            CUR_Func_move( &CUR.zp0, A, B );
+            CUR_Func_move( &exc->zp0, A, B );
         }
       }
       else
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Invalid_Reference );
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Invalid_Reference );
     }
 
   Fail:
-    CUR.new_top = CUR.args;
+    exc->new_top = exc->args;
   }
 
 
@@ -7636,20 +7632,20 @@
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
     /* Delta hinting is covered by US Patent 5159668. */
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
       FT_Long  n = args[0] * 2;
 
 
-      if ( CUR.args < n )
+      if ( exc->args < n )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        n = CUR.args;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        n = exc->args;
       }
 
-      CUR.args -= n;
-      CUR.new_top = CUR.args;
+      exc->args -= n;
+      exc->new_top = exc->args;
       return;
     }
 #endif
@@ -7659,24 +7655,24 @@
 
     for ( k = 1; k <= nump; k++ )
     {
-      if ( CUR.args < 2 )
+      if ( exc->args < 2 )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        CUR.args = 0;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        exc->args = 0;
         goto Fail;
       }
 
-      CUR.args -= 2;
+      exc->args -= 2;
 
-      A = (FT_ULong)CUR.stack[CUR.args + 1];
-      B = CUR.stack[CUR.args];
+      A = (FT_ULong)exc->stack[exc->args + 1];
+      B = exc->stack[exc->args];
 
-      if ( BOUNDSL( A, CUR.cvtSize ) )
+      if ( BOUNDSL( A, exc->cvtSize ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
@@ -7684,7 +7680,7 @@
       {
         C = ( (FT_ULong)B & 0xF0 ) >> 4;
 
-        switch ( CUR.opcode )
+        switch ( exc->opcode )
         {
         case 0x73:
           break;
@@ -7698,7 +7694,7 @@
           break;
         }
 
-        C += CUR.GS.delta_base;
+        C += exc->GS.delta_base;
 
         if ( P == C )
         {
@@ -7705,7 +7701,7 @@
           B = ( (FT_ULong)B & 0xF ) - 8;
           if ( B >= 0 )
             B++;
-          B *= 1L << ( 6 - CUR.GS.delta_shift );
+          B *= 1L << ( 6 - exc->GS.delta_shift );
 
           CUR_Func_move_cvt( A, B );
         }
@@ -7713,7 +7709,7 @@
     }
 
   Fail:
-    CUR.new_top = CUR.args;
+    exc->new_top = exc->args;
   }
 
 
@@ -7746,11 +7742,11 @@
     /*                              */
     if ( SUBPIXEL_HINTING     &&
          ( args[0] & 1 ) != 0 &&
-         CUR.ignore_x_mode    )
+         exc->ignore_x_mode   )
     {
-      K = CUR.rasterizer_version;
+      K = exc->rasterizer_version;
       FT_TRACE7(( "Setting rasterizer version %d\n",
-                  CUR.rasterizer_version ));
+                  exc->rasterizer_version ));
     }
     else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -7762,7 +7758,7 @@
     /* Selector Bit:  1             */
     /* Return Bit(s): 8             */
     /*                              */
-    if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
+    if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
       K |= 0x80;
 
     /********************************/
@@ -7770,7 +7766,7 @@
     /* Selector Bit:  2             */
     /* Return Bit(s): 9             */
     /*                              */
-    if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
+    if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
       K |= 1 << 8;
 
     /********************************/
@@ -7778,17 +7774,17 @@
     /* Selector Bit:  5             */
     /* Return Bit(s): 12            */
     /*                              */
-    if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
+    if ( ( args[0] & 32 ) != 0 && exc->grayscale )
       K |= 1 << 12;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
-    if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
-         CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
+    if ( SUBPIXEL_HINTING                                     &&
+         exc->ignore_x_mode                                   &&
+         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
     {
 
-      if ( CUR.rasterizer_version >= 37 )
+      if ( exc->rasterizer_version >= 37 )
       {
         /********************************/
         /* HINTING FOR SUBPIXEL         */
@@ -7795,7 +7791,7 @@
         /* Selector Bit:  6             */
         /* Return Bit(s): 13            */
         /*                              */
-        if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
+        if ( ( args[0] & 64 ) != 0 && exc->subpixel )
           K |= 1 << 13;
 
         /********************************/
@@ -7804,7 +7800,7 @@
         /* Return Bit(s): 14            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
+        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
           K |= 1 << 14;
 
         /********************************/
@@ -7813,7 +7809,7 @@
         /* Return Bit(s): 15            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
+        if ( ( args[0] & 256 ) != 0 && exc->symmetrical_smoothing )
           K |= 1 << 15;
 
         /********************************/
@@ -7822,10 +7818,10 @@
         /* Return Bit(s): 16            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 512 ) != 0 && CUR.bgr )
+        if ( ( args[0] & 512 ) != 0 && exc->bgr )
           K |= 1 << 16;
 
-        if ( CUR.rasterizer_version >= 38 )
+        if ( exc->rasterizer_version >= 38 )
         {
           /********************************/
           /* SUBPIXEL POSITIONED?         */
@@ -7833,7 +7829,7 @@
           /* Return Bit(s): 17            */
           /*                              */
           /* Functionality still needs to be added */
-          if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
+          if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
             K |= 1 << 17;
         }
       }
@@ -7848,8 +7844,8 @@
   static void
   Ins_UNKNOWN( INS_ARG )
   {
-    TT_DefRecord*  def   = CUR.IDefs;
-    TT_DefRecord*  limit = def + CUR.numIDefs;
+    TT_DefRecord*  def   = exc->IDefs;
+    TT_DefRecord*  limit = def + exc->numIDefs;
 
     FT_UNUSED_ARG;
 
@@ -7856,32 +7852,32 @@
 
     for ( ; def < limit; def++ )
     {
-      if ( (FT_Byte)def->opc == CUR.opcode && def->active )
+      if ( (FT_Byte)def->opc == exc->opcode && def->active )
       {
         TT_CallRec*  call;
 
 
-        if ( CUR.callTop >= CUR.callSize )
+        if ( exc->callTop >= exc->callSize )
         {
-          CUR.error = FT_THROW( Stack_Overflow );
+          exc->error = FT_THROW( Stack_Overflow );
           return;
         }
 
-        call = CUR.callStack + CUR.callTop++;
+        call = exc->callStack + exc->callTop++;
 
-        call->Caller_Range = CUR.curRange;
-        call->Caller_IP    = CUR.IP + 1;
+        call->Caller_Range = exc->curRange;
+        call->Caller_IP    = exc->IP + 1;
         call->Cur_Count    = 1;
         call->Def          = def;
 
         INS_Goto_CodeRange( def->range, def->start );
 
-        CUR.step_ins = FALSE;
+        exc->step_ins = FALSE;
         return;
       }
     }
 
-    CUR.error = FT_THROW( Invalid_Opcode );
+    exc->error = FT_THROW( Invalid_Opcode );
   }
 
 
@@ -8233,26 +8229,26 @@
 #endif
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    CUR.iup_called = FALSE;
+    exc->iup_called = FALSE;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* set PPEM and CVT functions */
-    CUR.tt_metrics.ratio = 0;
-    if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+    exc->tt_metrics.ratio = 0;
+    if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
     {
       /* non-square pixels, use the stretched routines */
-      CUR.func_cur_ppem  = Current_Ppem_Stretched;
-      CUR.func_read_cvt  = Read_CVT_Stretched;
-      CUR.func_write_cvt = Write_CVT_Stretched;
-      CUR.func_move_cvt  = Move_CVT_Stretched;
+      exc->func_cur_ppem  = Current_Ppem_Stretched;
+      exc->func_read_cvt  = Read_CVT_Stretched;
+      exc->func_write_cvt = Write_CVT_Stretched;
+      exc->func_move_cvt  = Move_CVT_Stretched;
     }
     else
     {
       /* square pixels, use normal routines */
-      CUR.func_cur_ppem  = Current_Ppem;
-      CUR.func_read_cvt  = Read_CVT;
-      CUR.func_write_cvt = Write_CVT;
-      CUR.func_move_cvt  = Move_CVT;
+      exc->func_cur_ppem  = Current_Ppem;
+      exc->func_read_cvt  = Read_CVT;
+      exc->func_write_cvt = Write_CVT;
+      exc->func_move_cvt  = Move_CVT;
     }
 
     COMPUTE_Funcs();
@@ -8260,55 +8256,55 @@
 
     do
     {
-      CUR.opcode = CUR.code[CUR.IP];
+      exc->opcode = exc->code[exc->IP];
 
       FT_TRACE7(( "  " ));
-      FT_TRACE7(( opcode_name[CUR.opcode] ));
+      FT_TRACE7(( opcode_name[exc->opcode] ));
       FT_TRACE7(( "\n" ));
 
-      if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+      if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
       {
-        if ( CUR.IP + 1 >= CUR.codeSize )
+        if ( exc->IP + 1 >= exc->codeSize )
           goto LErrorCodeOverflow_;
 
-        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
       }
 
-      if ( CUR.IP + CUR.length > CUR.codeSize )
+      if ( exc->IP + exc->length > exc->codeSize )
         goto LErrorCodeOverflow_;
 
       /* First, let's check for empty stack and overflow */
-      CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
+      exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
 
       /* `args' is the top of the stack once arguments have been popped. */
       /* One can also interpret it as the index of the last argument.    */
-      if ( CUR.args < 0 )
+      if ( exc->args < 0 )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Too_Few_Arguments );
+          exc->error = FT_THROW( Too_Few_Arguments );
           goto LErrorLabel_;
         }
 
         /* push zeroes onto the stack */
-        for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ )
-          CUR.stack[i] = 0;
-        CUR.args = 0;
+        for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
+          exc->stack[i] = 0;
+        exc->args = 0;
       }
 
-      CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );
+      exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
 
       /* `new_top' is the new top of the stack, after the instruction's */
       /* execution.  `top' will be set to `new_top' after the `switch'  */
       /* statement.                                                     */
-      if ( CUR.new_top > CUR.stackSize )
+      if ( exc->new_top > exc->stackSize )
       {
-        CUR.error = FT_THROW( Stack_Overflow );
+        exc->error = FT_THROW( Stack_Overflow );
         goto LErrorLabel_;
       }
 
-      CUR.step_ins = TRUE;
-      CUR.error    = FT_Err_Ok;
+      exc->step_ins = TRUE;
+      exc->error    = FT_Err_Ok;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
@@ -8316,8 +8312,8 @@
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
-          if ( opcode_pointer[i] < opcode_size[i]                 &&
-               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+          if ( opcode_pointer[i] < opcode_size[i]                  &&
+               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
           {
             opcode_pointer[i] += 1;
 
@@ -8325,8 +8321,8 @@
             {
               FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
                           i,
-                          CUR.face->root.family_name,
-                          CUR.face->root.style_name ));
+                          exc->face->root.family_name,
+                          exc->face->root.style_name ));
 
               switch ( i )
               {
@@ -8346,8 +8342,8 @@
 #ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
 
       {
-        FT_Long*  args   = CUR.stack + CUR.args;
-        FT_Byte   opcode = CUR.opcode;
+        FT_Long*  args   = exc->stack + exc->args;
+        FT_Byte   opcode = exc->opcode;
 
 
 #undef  ARRAY_BOUND_ERROR
@@ -8371,11 +8367,11 @@
 
             if ( opcode < 4 )
             {
-              CUR.GS.projVector.x = AA;
-              CUR.GS.projVector.y = BB;
+              exc->GS.projVector.x = AA;
+              exc->GS.projVector.y = BB;
 
-              CUR.GS.dualVector.x = AA;
-              CUR.GS.dualVector.y = BB;
+              exc->GS.dualVector.x = AA;
+              exc->GS.dualVector.y = BB;
             }
             else
             {
@@ -8384,8 +8380,8 @@
 
             if ( ( opcode & 2 ) == 0 )
             {
-              CUR.GS.freeVector.x = AA;
-              CUR.GS.freeVector.y = BB;
+              exc->GS.freeVector.x = AA;
+              exc->GS.freeVector.y = BB;
             }
             else
             {
@@ -8614,7 +8610,7 @@
           break;
 
       Set_Invalid_Ref:
-            CUR.error = FT_THROW( Invalid_Reference );
+            exc->error = FT_THROW( Invalid_Reference );
           break;
 
         case 0x43:  /* RS */
@@ -8900,38 +8896,38 @@
 
 #else
 
-      Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
+      Instruct_Dispatch[exc->opcode]( EXEC_ARG_ &exc->stack[exc->args] );
 
 #endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
 
-      if ( CUR.error )
+      if ( exc->error )
       {
-        switch ( CUR.error )
+        switch ( exc->error )
         {
           /* looking for redefined instructions */
         case FT_ERR( Invalid_Opcode ):
           {
-            TT_DefRecord*  def   = CUR.IDefs;
-            TT_DefRecord*  limit = def + CUR.numIDefs;
+            TT_DefRecord*  def   = exc->IDefs;
+            TT_DefRecord*  limit = def + exc->numIDefs;
 
 
             for ( ; def < limit; def++ )
             {
-              if ( def->active && CUR.opcode == (FT_Byte)def->opc )
+              if ( def->active && exc->opcode == (FT_Byte)def->opc )
               {
                 TT_CallRec*  callrec;
 
 
-                if ( CUR.callTop >= CUR.callSize )
+                if ( exc->callTop >= exc->callSize )
                 {
-                  CUR.error = FT_THROW( Invalid_Reference );
+                  exc->error = FT_THROW( Invalid_Reference );
                   goto LErrorLabel_;
                 }
 
-                callrec = &CUR.callStack[CUR.callTop];
+                callrec = &exc->callStack[exc->callTop];
 
-                callrec->Caller_Range = CUR.curRange;
-                callrec->Caller_IP    = CUR.IP + 1;
+                callrec->Caller_Range = exc->curRange;
+                callrec->Caller_IP    = exc->IP + 1;
                 callrec->Cur_Count    = 1;
                 callrec->Def          = def;
 
@@ -8943,7 +8939,7 @@
             }
           }
 
-          CUR.error = FT_THROW( Invalid_Opcode );
+          exc->error = FT_THROW( Invalid_Opcode );
           goto LErrorLabel_;
 
 #if 0
@@ -8961,10 +8957,10 @@
         }
       }
 
-      CUR.top = CUR.new_top;
+      exc->top = exc->new_top;
 
-      if ( CUR.step_ins )
-        CUR.IP += CUR.length;
+      if ( exc->step_ins )
+        exc->IP += exc->length;
 
       /* increment instruction counter and check if we didn't */
       /* run this program for too long (e.g. infinite loops). */
@@ -8972,17 +8968,17 @@
         return FT_THROW( Execution_Too_Long );
 
     LSuiteLabel_:
-      if ( CUR.IP >= CUR.codeSize )
+      if ( exc->IP >= exc->codeSize )
       {
-        if ( CUR.callTop > 0 )
+        if ( exc->callTop > 0 )
         {
-          CUR.error = FT_THROW( Code_Overflow );
+          exc->error = FT_THROW( Code_Overflow );
           goto LErrorLabel_;
         }
         else
           goto LNo_Error_;
       }
-    } while ( !CUR.instruction_trap );
+    } while ( !exc->instruction_trap );
 
   LNo_Error_:
 
@@ -8993,7 +8989,7 @@
     return FT_Err_Ok;
 
   LErrorCodeOverflow_:
-    CUR.error = FT_THROW( Code_Overflow );
+    exc->error = FT_THROW( Code_Overflow );
 
   LErrorLabel_:
 
@@ -9004,16 +9000,16 @@
     /* If any errors have occurred, function tables may be broken. */
     /* Force a re-execution of `prep' and `fpgm' tables if no      */
     /* bytecode debugger is run.                                   */
-    if ( CUR.error                          &&
-         !CUR.instruction_trap              &&
-         CUR.curRange == tt_coderange_glyph )
+    if ( exc->error                          &&
+         !exc->instruction_trap              &&
+         exc->curRange == tt_coderange_glyph )
     {
-      FT_TRACE1(( "  The interpreter returned error 0x%x\n", CUR.error ));
+      FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
       exc->size->bytecode_ready = -1;
       exc->size->cvt_ready      = -1;
     }
 
-    return CUR.error;
+    return exc->error;
   }