Beispiel #1
0
FALCON_FUNC  mth_dictValues( ::Falcon::VMachine *vm )
{
   Item *i_dict;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
   }
   else {
      i_dict = vm->param(0);
      if( i_dict == 0  || ! i_dict->isDict() ) 
      {
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
               .origin( e_orig_runtime )
               .extra( "D" ) );
      }
   }

   CoreDict *dict = i_dict->asDict();
   CoreArray *array = new CoreArray;
   array->reserve( dict->length() );
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      array->append( iter.getCurrent() );
      iter.next();
   }

   vm->retval( array );
}
Beispiel #2
0
FALCON_FUNC  Dictionary_mfcomp ( ::Falcon::VMachine *vm )
{
	Item* i_func = vm->param(0);

   if ( i_func == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "C, ..." ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   StackFrame* current = vm->currentFrame();

   Item i_check = *i_func;

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, i_check );
   }
   else {
      dict->items().comprehension_start( vm, dict, i_check );
   }

   for( uint32 i = 1; i < current->m_param_count; ++i )
   {
      vm->pushParam( current->m_params[i] );
   }
}
Beispiel #3
0
FALCON_FUNC  Dictionary_comp ( ::Falcon::VMachine *vm )
{
   if ( vm->param(0) == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "R|A|C|Sequence, [C]" ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();

   Item i_gen = *vm->param(0);
   Item i_check = vm->param(1) == 0 ? Item(): *vm->param(1);

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, i_check );
   }
   else {
      dict->items().comprehension_start( vm, dict, i_check );
   }

   vm->pushParam( i_gen );
}
Beispiel #4
0
FALCON_FUNC  Dictionary_do ( ::Falcon::VMachine *vm )
{
	Item* i_func = vm->param(0);

   if ( i_func == 0 || ! i_func->isCallable() )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .extra( "C, ..." ) );
   }

   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   if ( dict->empty() )
   {
   	vm->retnil();
   	return;
   }


   Iterator* iter = new Iterator(&dict->items());
   vm->addLocals(1);
   *vm->local(0) = new GarbagePointer(iter);
   vm->returnHandler( Dictionary_do_next );

   // do the first call.
   vm->pushParam( iter->getCurrentKey() );
	vm->pushParam( iter->getCurrent() );
	vm->callFrame( *vm->param(0), 2 );
}
Beispiel #5
0
/*# @method setFields URI
   @brief Sets query fields for this uri.
   @param fields A dictionary of fields or nil to clear the query.
   @raise ParamError if the input dictionary contains non-string values.
*/
FALCON_FUNC  URI_setFields ( ::Falcon::VMachine *vm )
{
   UriObject *self = dyncast<UriObject*>( vm->self().asObject() );
   URI &uri = self->uri();

   Item *p0 = vm->param(0);

   if ( ( p0 == 0 ) || ( ! p0->isDict() ) )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ ).
         origin( e_orig_runtime ).extra( "S" ) );
      return;
   }

   CoreDict *dict = p0->asDict();
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      if ( ( !iter.getCurrentKey().isString()) || (! iter.getCurrent().isString() ) )
      {
         throw new ParamError( ErrorParam( e_inv_params, __LINE__ ).
            origin( e_orig_runtime ).extra( "S" ) );
         return;
      }

      uri.setField( *iter.getCurrentKey().asString(), *iter.getCurrent().asString() );
      iter.next();
   }

   uri.makeQuery();
}
Beispiel #6
0
/*#
   @function dictFront
   @brief Returns the first item in the dictionary.
   @param dict The dictionary on which to operate.
   @optparam remove If true, remove the dictionary entry too.
   @optparam key If true, return the key instead of the value.
   @return The first value (or key) in the dictionary.
   @raise AccessError if the dictionary is empty
*/
FALCON_FUNC  mth_dictFront( ::Falcon::VMachine *vm )
{
   CoreDict* dict; 
   bool bKey; 
   bool bRemove;
   
   process_dictFrontBackParams( vm, dict, bKey, bRemove );
   Iterator iter( &dict->items() );
   if ( bKey )
      vm->retval( iter.getCurrentKey() );
   else
      vm->retval( iter.getCurrent() );
   
   if ( bRemove )
      iter.erase();
}
Beispiel #7
0
/*#
   @method fill Dictionary
   @brief Fills the array with the given element.
   @param item The item to be replicated.
   @return This dictionary.

   This method allows to clear all the values in this dictionary, 
   resetting all the elements to a default value.
*/
FALCON_FUNC  mth_dictFill ( ::Falcon::VMachine *vm )
{
   Item *i_dict;
   Item *i_item;
   
   if ( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_item = vm->param(0);
   }
   else
   {
      i_dict = vm->param(0);
      i_item = vm->param(1);
   }

   if ( i_dict == 0 || ! i_dict->isDict() 
         || i_item == 0 )
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
         .origin( e_orig_runtime )
         .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Iterator iter( &dict->items() );

   while( iter.hasCurrent() )
   {
      if ( i_item->isString() )
         iter.getCurrent() = new CoreString( *i_item->asString() );
      else
         iter.getCurrent() = *i_item;
      
      iter.next();
   }
   
   vm->retval( dict );
}
Beispiel #8
0
FALCON_FUNC  Dictionary_mcomp ( ::Falcon::VMachine *vm )
{
   // Save the parameters as the stack may change greatly.
   CoreDict* dict = vm->self().asDict();
   StackFrame* current = vm->currentFrame();

   // if this is a blessed dictionary, we must use the append method.
   if ( dict->isBlessed() )
   {
      // this will throw if dict has not "append"
      PoopSeq *seq = new PoopSeq( vm, dict );
      vm->pushParam( new GarbagePointer( seq ) );
      seq->comprehension_start( vm, dict, Item() );
   }
   else {
      dict->items().comprehension_start( vm, dict, Item() );
   }

   for( uint32 i = 0; i < current->m_param_count; ++i )
   {
      vm->pushParam( current->m_params[i] );
   }
}
Beispiel #9
0
FALCON_FUNC  mth_dictFind( ::Falcon::VMachine *vm )
{
   Item *i_dict, *i_key;
   
   if( vm->self().isMethodic() )
   {
      i_dict = &vm->self();
      i_key = vm->param(0);
   }
   else {
      i_dict = vm->param(0);
      i_key = vm->param(1);
   }
   
   if( i_dict == 0  || ! i_dict->isDict() || i_key == 0 ) 
   {
      throw new ParamError( ErrorParam( e_inv_params, __LINE__ )
            .origin( e_orig_runtime )
            .extra( vm->self().isMethodic() ? "X" : "D,X" ) );
   }

   CoreDict *dict = i_dict->asDict();
   Iterator iter( &dict->items() );

   if ( ! dict->findIterator( *i_key, iter ) )
      vm->retnil();
   else 
   {
      // find the iterator class, we'll need it
      Item *i_iclass = vm->findWKI( "Iterator" );
      fassert( i_iclass != 0 );
      
      CoreObject *ival = i_iclass->asClass()->createInstance( new Iterator( iter ) );
      ival->setProperty( "_origin", *i_dict );
      vm->retval( ival );
   }
}
Beispiel #10
0
static void describe_internal( VMachine *vm, String &tgt, const Item *elem, int32 level, int32 maxLevel, int32 maxSize )
{
   uint32 count;

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      tgt += "...";
      return;
   }

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         tgt += "Nil";
      break;

      case FLC_ITEM_UNB:
         tgt += "_";
      break;


      case FLC_ITEM_BOOL:
         tgt += elem->asBoolean() ? "true" : "false";
      break;


      case FLC_ITEM_INT:
         tgt.writeNumber( elem->asInteger() );
      break;

      case FLC_ITEM_NUM:
         tgt.writeNumber( elem->asNumeric(), "%g" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(tgt);
      break;

      case FLC_ITEM_STRING:
         tgt += "\"";
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            tgt += *elem->asString();
            tgt += "\"";
         }
         else {
            tgt += elem->asString()->subString(0, maxSize );
            tgt += " ... \"";
         }
      break;

      case FLC_ITEM_LBIND:
         tgt += "&";
         tgt += *elem->asLBind();
         if (elem->isFutureBind())
         {
            tgt +="|";
            describe_internal( vm, tgt, &elem->asFutureBind(), level+1, maxLevel, maxSize );
         }
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         tgt += "MB(";
         tgt.writeNumber( (int64) mb->length() );
         tgt += ",";
         tgt.writeNumber( (int64) mb->wordSize() );
         tgt += ")";

         tgt += " [";

         String fmt;
         int limit = 0;
         switch ( mb->wordSize() )
         {
            case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
            case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
            case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
            case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
         }

         uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
         for( count = 0; count < max; count++ )
         {
            tgt.writeNumber( (int64)  mb->get( count ), fmt );
            tgt += " ";
         }
         if ( count == (uint32) maxSize )
            tgt += " ...";
         tgt += "]";
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...]";
            break;
         }

         for( count = 0; count < arr->length(); count++ ) {
            if ( count == 0 ) tgt += " ";

            describe_internal( vm, tgt, & ((*arr)[count]), level + 1, maxLevel, maxSize );

            if ( count + 1 < arr->length() )
               tgt += ", ";
         }

         tgt +="]";
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         if( dict->isBlessed() )
            tgt += "*";

         tgt += "[";

         if ( level == maxLevel )
         {
            tgt += "...=>...]";
            break;
         }

         if ( dict->length() == 0 )
         {
            tgt += "=>]";
            break;
         }

         Item key, value;
         Iterator iter( &dict->items() );

         // separate the first loop to be able to add ", "
         describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
         tgt += " => ";
         describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
         iter.next();
         while( iter.hasCurrent() )
         {
            tgt += ", ";
            describe_internal( vm, tgt, &iter.getCurrentKey(), level + 1, maxLevel, maxSize );
            tgt += " => ";
            describe_internal( vm, tgt, &iter.getCurrent(), level + 1, maxLevel, maxSize );
            iter.next();
         }

         tgt += "]";
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         tgt += arr->generator()->symbol()->name() + "(){ ";

         if ( level == maxLevel )
         {
            tgt += "...}";
            break;
         }

         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            const String &propName = *pt.getKey( count );
			
			// write only?
			if ( pt.getEntry( count ).isWriteOnly() )
			{
				tgt.A( "(" ).A( propName ).A(")");
			}
			else
			{
				Item dummy;
				arr->getProperty( propName, dummy );

				// in describe skip methods.
				if ( dummy.isFunction() || dummy.isMethod() )
				   continue;
				
				tgt += propName + " = ";

				describe_internal( vm, tgt, &dummy, level + 1, maxLevel, maxSize );
			}

            if (count+1 < pt.added())
            {
               tgt += ", ";
            }
         }

         tgt += "}";
      }
      break;

      case FLC_ITEM_CLASS:
         tgt += "Class " + elem->asClass()->symbol()->name();
      break;

      case FLC_ITEM_METHOD:
      {
         tgt += "(";
         Item itemp;
         elem->getMethodItem( itemp );
         describe_internal( vm, tgt, &itemp, level + 1, maxLevel, maxSize );
         tgt += ").";
         tgt += elem->asMethodFunc()->name() + "()";
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         tgt += "Class ";
         tgt += elem->asMethodClassOwner()->generator()->symbol()->name();
         tgt += "." + elem->asMethodClass()->symbol()->name() + "()";
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();
         tgt += funcSym->name() + "()";
      }
      break;

      case FLC_ITEM_REFERENCE:
         tgt += "->";
         describe_internal( vm, tgt, elem->dereference(), level + 1, maxLevel, maxSize );
      break;

      default:
         tgt += "?";
   }
}
Beispiel #11
0
void inspect_internal( VMachine *vm, const Item *elem, int32 level, int32 maxLevel, int32 maxSize, Item* i_stream, bool add, bool addline )
{

   uint32 count;
   int32 i;
   Stream *stream = i_stream != 0 ?
         dyncast<Stream*>(i_stream->asObjectSafe()->getFalconData()) :
         vm->stdErr();

   // return if we reached the maximum level.
   if ( maxLevel >= 0 && level > maxLevel )
   {
      stream->writeString( "..." );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   if ( stream == 0 )
   {
      stream = vm->stdOut();
      if ( stream == 0 )
         return;
   }

   if ( add )
      for ( i = 0; i < level*3; i ++ )
      {
         stream->put( 0x20 ); // space
      }

   if ( elem == 0 ) {
      stream->writeString( "Nothing" );
      if ( addline )
         stream->writeString( "\n" );
      return;
   }

   String temp;

   switch( elem->type() )
   {
      case FLC_ITEM_NIL:
         stream->writeString( "Nil" );
      break;

      case FLC_ITEM_UNB:
            stream->writeString( "_" );
      break;

      case FLC_ITEM_BOOL:
         stream->writeString( elem->asBoolean() ? "true" : "false" );
      break;


      case FLC_ITEM_INT:
         temp.writeNumber( elem->asInteger() );
         stream->writeString( "int(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_NUM:
         temp.writeNumber( elem->asNumeric(), "%g" );
         stream->writeString( "num(" );
         stream->writeString( temp );
         stream->writeString( ")" );
      break;

      case FLC_ITEM_RANGE:
         elem->toString(temp);
         stream->writeString( temp );
      break;

      case FLC_ITEM_STRING:
         stream->writeString( "\"" );
         if ( maxSize < 0 || elem->asString()->length() < (uint32) maxSize )
         {
            stream->writeString( *elem->asString() );
            stream->writeString( "\"" );
         }
         else {
            stream->writeString( elem->asString()->subString(0, maxSize ) );
            stream->writeString( " ... \"" );
         }
      break;

      case FLC_ITEM_LBIND:
         stream->writeString( "&" );
         stream->writeString( *elem->asLBind() );
      break;

      case FLC_ITEM_MEMBUF:
      {
         MemBuf *mb = elem->asMemBuf();
         temp = "MemBuf(";
         temp.writeNumber( (int64) mb->length() );
         temp += ",";
         temp.writeNumber( (int64) mb->wordSize() );
         temp += ")";

         if ( maxSize == 0 )
            stream->writeString( temp );
         else {
            temp += " [\n";

            String fmt;
            int limit = 0;
            switch ( mb->wordSize() )
            {
               case 1: fmt = "%02" LLFMT "X"; limit = 24; break;
               case 2: fmt = "%04" LLFMT "X"; limit = 12; break;
               case 3: fmt = "%06" LLFMT "X"; limit = 9; break;
               case 4: fmt = "%08" LLFMT "X"; limit = 6; break;
            }

            int written = 0;
            uint32 max = maxSize < 0 || mb->length() < (uint32) maxSize ? mb->length() : (uint32) maxSize;
            for( count = 0; count < max; count++ )
            {
               temp.writeNumber( (int64)  mb->get( count ), fmt );
               temp += " ";
               written ++;
               if ( written == limit )
               {
                  temp += "\n";
                  written = 0;
               }
               stream->writeString( temp );
               temp = "";
            }
            if ( count == (uint32) maxSize )
               stream->writeString( " ... " );
            stream->writeString( "]" );
         }
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         CoreArray *arr = elem->asArray();
         temp = "Array[";
         temp.writeNumber( (int64) arr->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         for( count = 0; count < arr->length(); count++ ) {
            inspect_internal( vm, & ((*arr)[count]), level + 1, maxLevel, maxSize, i_stream, true, true );
         }

         for ( i = 0; i < level; i ++ )
         {
            stream->writeString( "   " );
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_DICT:
      {
         CoreDict *dict = elem->asDict();
         temp = "Dict[";
         temp.writeNumber( (int64) dict->length() );
         temp += "]";
         stream->writeString( temp );

         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( "{\n" );

         Iterator iter( &dict->items() );
         while( iter.hasCurrent() )
         {
            inspect_internal( vm, &iter.getCurrentKey(), level + 1, maxLevel, maxSize, i_stream, true, false );
            stream->writeString( " => " );
            inspect_internal( vm, &iter.getCurrent(), level + 1, maxLevel, maxSize, i_stream, false, true );
            iter.next();
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_OBJECT:
      {
         CoreObject *arr = elem->asObjectSafe();
         stream->writeString( "Object of class " + arr->generator()->symbol()->name() );
         if ( level == maxLevel )
         {
            stream->writeString( "{...}" );
            break;
         }

         stream->writeString( " {\n" );
         const PropertyTable &pt = arr->generator()->properties();

         for( count = 0; count < pt.added() ; count++ )
         {
            for ( i = 0; i < (level+1); i ++ )
            {
               stream->writeString("   ");
            }
            const String &propName = *pt.getKey( count );
			
			if ( pt.getEntry(count).isWriteOnly() )
			{
				stream->writeString( "(" );
				stream->writeString( propName + ")\n" );
			}
			else 
			{
				stream->writeString( propName + " => " );
				Item dummy;
				arr->getProperty( propName, dummy);
				inspect_internal( vm, &dummy, level + 1, maxLevel, maxSize, i_stream, false, true );
			}
         }
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLASS:
         stream->writeString( "Class " + elem->asClass()->symbol()->name() );
      break;

      case FLC_ITEM_METHOD:
      {
         temp = "Method ";
         temp += "->" + elem->asMethodFunc()->name();
         stream->writeString( temp );

         Item itemp;
         elem->getMethodItem( itemp );

         inspect_internal( vm, &itemp, level + 1, maxLevel, maxSize, i_stream, true, true );
         for ( i = 0; i < level; i ++ )
         {
            stream->writeString("   ");
         }
         stream->writeString( "}" );
      }
      break;

      case FLC_ITEM_CLSMETHOD:
         temp = "Cls.Method 0x";
         temp.writeNumberHex( (uint64) elem->asMethodClassOwner() );
         temp += "->" + elem->asMethodClass()->symbol()->name();
         stream->writeString( temp );
      break;

      case FLC_ITEM_FUNC:
      {
         const Symbol *funcSym = elem->asFunction()->symbol();

         if ( funcSym->isExtFunc() )
         {
            stream->writeString( "Ext. Function " + funcSym->name() );
         }
         else {
            stream->writeString( "Function " + funcSym->name() );

            FuncDef *def = funcSym->getFuncDef();
            uint32 itemId = def->onceItemId();
            if ( itemId != FuncDef::NO_STATE )
            {
               if ( elem->asFunction()->liveModule()->globals()[ itemId ].isNil() )
                  stream->writeString( "{ not called }");
               else
                  stream->writeString( "{ called }");
            }
         }
      }
      break;

      case FLC_ITEM_REFERENCE:
         stream->writeString( "Ref to " );
         inspect_internal( vm, elem->dereference(), level + 1, maxLevel, maxSize, i_stream, false, true );
      break;

      default:
         stream->writeString( "Invalid type");
   }
   if ( addline )
      stream->writeString( "\n" );

   stream->flush();
}
Beispiel #12
0
Item::e_sercode Item::serialize( Stream *file, bool bLive ) const
{
   if( file->bad() )
      return sc_ferror;

   switch( this->type() )
   {
      case FLC_ITEM_BOOL:
      {
         byte type = FLC_ITEM_BOOL;
         file->write((byte *) &type, 1 );

         byte bval = this->asBoolean() ? 1 : 0;
         file->write( (byte *) &bval, sizeof( bval ) );
      }
      break;

      case FLC_ITEM_INT:
      {
         byte type = FLC_ITEM_INT;
         file->write((byte *) &type, 1 );

         int64 val = endianInt64( this->asInteger() );
         file->write( (byte *) &val, sizeof( val ) );
      }
      break;

      case FLC_ITEM_RANGE:
      {
         byte type = FLC_ITEM_RANGE;
         file->write((byte *) &type, 1 );

         int64 val1 = endianInt64(this->asRangeStart());
         int64 val2 = endianInt64(this->asRangeEnd());
         int64 val3 = endianInt64(this->asRangeStep());
         //byte isOpen = this->asRangeIsOpen() ? 1 : 0;

         file->write( (byte *) &val1, sizeof( val1 ) );
         file->write( (byte *) &val2, sizeof( val2 ) );
         file->write( (byte *) &val3, sizeof( val3 ) );
         //file->write( (byte *) &isOpen, sizeof( isOpen ) );
      }
      break;

      case FLC_ITEM_NUM:
      {
         byte type = FLC_ITEM_NUM;
         file->write((byte *) &type, 1 );

         numeric val = endianNum( this->asNumeric() );
         file->write( (byte *) &val, sizeof( val ) );
      }
      break;

      case FLC_ITEM_STRING:
      {
         byte type = FLC_ITEM_STRING;
         file->write((byte *) &type, 1 );
         this->asString()->serialize( file );
      }
      break;

      case FLC_ITEM_LBIND:
      {
         byte type = FLC_ITEM_LBIND;
         file->write((byte *) &type, 1 );
         // Future bindings are temporary items; as such, their future
         // value is not to be serialized.
         asLBind()->serialize( file );
      }
      break;

      case FLC_ITEM_MEMBUF:
      {
         byte type = FLC_ITEM_MEMBUF;
         if ( bLive )
         {
            type |= 0x80;
            file->write( &type, 1 );
            MemBuf* mb = asMemBuf();
            file->write( &mb, sizeof(mb) );
         }
         else {
            file->write( &type, 1 );
            this->asMemBuf()->serialize( file, bLive );
         }
      }
      break;

      case FLC_ITEM_ARRAY:
      {
         byte type = FLC_ITEM_ARRAY;
         file->write((byte *) &type, 1 );

         CoreArray &array = *this->asArray();
         int32 len = endianInt32( array.length() );
         file->write( (byte *) &len, sizeof( len ) );
         for( uint32 i = 0; i < array.length(); i ++ ) {
            array[i].serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;
         }
      }
      break;

      case FLC_ITEM_DICT:
      {
         byte type = FLC_ITEM_DICT;
         file->write( &type, 1 );

         CoreDict *dict = this->asDict();
         type = dict->isBlessed() ? 1:0;
         file->write( &type, 1 );

         int32 len = endianInt32( dict->length() );
         file->write( (byte *) &len, sizeof( len ) );

         Iterator iter( &dict->items() );
         while( iter.hasCurrent() )
         {
            iter.getCurrentKey().serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;
            iter.getCurrent().serialize( file, bLive );
            if( ! file->good() )
               return sc_ferror;

            iter.next();
         }
      }
      break;

      case FLC_ITEM_FUNC:
         serialize_function( file, this->asFunction(), bLive );
      break;

      case FLC_ITEM_METHOD:
      {
         byte type = FLC_ITEM_METHOD;
         file->write( &type, 1 );

         e_sercode sc = asMethodItem().serialize( file, bLive );
         if( sc != sc_ok )
            return sc;

         CallPoint* cp = this->asMethodFunc();
         if ( cp->isFunc() )
         {
            serialize_function( file, static_cast<CoreFunc*>(cp), bLive );
         }
         else
         {
            SafeItem arr( static_cast<CoreArray*>(cp) );
            arr.serialize(file, bLive );
         }
      }
      break;

      case FLC_ITEM_OBJECT:
         serialize_object( file, this->asObjectSafe(), bLive );
      break;

      case FLC_ITEM_REFERENCE:
         asReference()->origin().serialize( file, bLive );
      break;

      case FLC_ITEM_CLASS:
         serialize_class( file, this->asClass() );
      break;

      case FLC_ITEM_CLSMETHOD:
         serialize_class( file, this->asMethodClass() );
         serialize_function( file, this->asFunction(), bLive );
      break;

      case FLC_ITEM_UNB:
      {
         byte type = FLC_ITEM_UNB;
         file->write((byte *) &type, 1 );
      }
      break;

      default:
      {
         byte type = FLC_ITEM_NIL;
         file->write((byte *) &type, 1 );
      }
   }

   return file->bad() ? sc_ferror : sc_ok;
}