(self, preserve_common, preserve_all)
Preserve COMMON variables.
Preserve COMMON variables.
Preserve COMMON variables .
def preserve_commons(self, preserve_common, preserve_all):
        """Preserve COMMON variables."""
        # preserve COMMON variables
        if preserve_all:
            preserve_sc, preserve_ar = self.scalars, self.arrays
        elif preserve_common:
            preserve_sc, preserve_ar = preserve_common
        else:
            preserve_sc, preserve_ar = set(), set()
        # do not collect garbage during string migration
        # it's not going to free up memory and it will break things
        with self.hold_garbage():
            string_store = values.StringSpace(self)
            # preserve scalars
            common_scalars = {
                name: self.scalars.get(name)
                for name in preserve_sc if name in self.scalars
            }
            # preserve arrays
            common_arrays = {
                name: (self.arrays.dimensions(name), bytearray(self.arrays.view_full_buffer(name)))
                for name in preserve_ar if name in self.arrays
            }
            scalar_strings = {
                name: value.to_pointer()
                for name, value in iteritems(common_scalars)
                if name[-1:] == values.STR
            }
            array_strings = {
                (name, _i): struct.unpack('<BH', value[1][_i:_i+3])
                for name, value in iteritems(common_arrays)
                for _i in range(0, len(value[1]), 3)
                if name[-1:] == values.STR
            }
            # sort by pointer address - items will be (name, (length, address))
            for name, pointer in sorted(
                    iteritems(scalar_strings), key=lambda _pair: _pair[1][1], reverse=True
                ):
                length, address = self.strings.copy_to(string_store, *pointer)
                common_scalars[name] = self.values.new_string().from_pointer(length, address)
            for item in sorted(
                    iteritems(array_strings), key=lambda _pair: _pair[1][1], reverse=True
                ):
                name, offset = item[0]
                pointer = item[1]
                # if the string array is not full, pointers are zero
                # but address is ignored for zero length
                length, address = self.strings.copy_to(string_store, *pointer)
                # modify the stored bytearray
                common_arrays[name][1][offset:offset+3] = struct.pack('<BH', length, address)
            yield
            # check if there is sufficient memory
            scalar_size = sum(self.scalars.memory_size(name) for name in common_scalars)
            array_size = sum(
                self.arrays.memory_size(name, val[0])
                for name, val in iteritems(common_arrays)
            )
            if self.var_start() + scalar_size + array_size > string_store.current:
                raise error.BASICError(error.OUT_OF_MEMORY)
            self.strings.rebuild(string_store)
            for name, value in iteritems(common_scalars):
                self.scalars.set(name, value)
            for name, value in iteritems(common_arrays):
                dimensions, buf = value
                self.arrays.allocate(name, dimensions)
                # copy the array buffers back
                self.arrays.view_full_buffer(name)[:] = buf
def preserve_commons ( self , preserve_common , preserve_all ) : # preserve COMMON variables if preserve_all : preserve_sc , preserve_ar = self . scalars , self . arrays elif preserve_common : preserve_sc , preserve_ar = preserve_common else : preserve_sc , preserve_ar = set ( ) , set ( ) # do not collect garbage during string migration # it's not going to free up memory and it will break things with self . hold_garbage ( ) : string_store = values . StringSpace ( self ) # preserve scalars common_scalars = { name : self . scalars . get ( name ) for name in preserve_sc if name in self . scalars } # preserve arrays common_arrays = { name : ( self . arrays . dimensions ( name ) , bytearray ( self . arrays . view_full_buffer ( name ) ) ) for name in preserve_ar if name in self . arrays } scalar_strings = { name : value . to_pointer ( ) for name , value in iteritems ( common_scalars ) if name [ - 1 : ] == values . STR } array_strings = { ( name , _i ) : struct . unpack ( '<BH' , value [ 1 ] [ _i : _i + 3 ] ) for name , value in iteritems ( common_arrays ) for _i in range ( 0 , len ( value [ 1 ] ) , 3 ) if name [ - 1 : ] == values . STR } # sort by pointer address - items will be (name, (length, address)) for name , pointer in sorted ( iteritems ( scalar_strings ) , key = lambda _pair : _pair [ 1 ] [ 1 ] , reverse = True ) : length , address = self . strings . copy_to ( string_store , * pointer ) common_scalars [ name ] = self . values . new_string ( ) . from_pointer ( length , address ) for item in sorted ( iteritems ( array_strings ) , key = lambda _pair : _pair [ 1 ] [ 1 ] , reverse = True ) : name , offset = item [ 0 ] pointer = item [ 1 ] # if the string array is not full, pointers are zero # but address is ignored for zero length length , address = self . strings . copy_to ( string_store , * pointer ) # modify the stored bytearray common_arrays [ name ] [ 1 ] [ offset : offset + 3 ] = struct . pack ( '<BH' , length , address ) yield # check if there is sufficient memory scalar_size = sum ( self . scalars . memory_size ( name ) for name in common_scalars ) array_size = sum ( self . arrays . memory_size ( name , val [ 0 ] ) for name , val in iteritems ( common_arrays ) ) if self . var_start ( ) + scalar_size + array_size > string_store . current : raise error . BASICError ( error . OUT_OF_MEMORY ) self . strings . rebuild ( string_store ) for name , value in iteritems ( common_scalars ) : self . scalars . set ( name , value ) for name , value in iteritems ( common_arrays ) : dimensions , buf = value self . arrays . allocate ( name , dimensions ) # copy the array buffers back self . arrays . view_full_buffer ( name ) [ : ] = buf