dvander@52: /* vim: set ts=4 sw=4 tw=99 et: dvander@52: * dvander@28: * Copyright (C) 2012 David Anderson dvander@28: * dvander@251: * This file is part of SourcePawn. dvander@28: * dvander@251: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@28: * the terms of the GNU General Public License as published by the Free dvander@28: * Software Foundation, either version 3 of the License, or (at your option) dvander@28: * any later version. dvander@28: * dvander@251: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@28: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@28: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@28: * dvander@28: * You should have received a copy of the GNU General Public License along with dvander@251: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@28: */ dvander@28: #ifndef _include_jitcraft_objects_h_ dvander@28: #define _include_jitcraft_objects_h_ dvander@28: dvander@28: #include "Utility.h" dvander@28: #include "Spaces.h" dvander@28: #include "Barriers.h" dvander@28: dvander@59: namespace ke { dvander@28: dvander@28: class Zone; dvander@28: dvander@28: // Garbage-collection objects require a header to describe their layout. This dvander@28: // header is called a "map". The different kinds of maps are enumerated below. dvander@28: class Map; dvander@28: dvander@28: enum MapKind dvander@28: { dvander@28: // Represents Type objects. dvander@28: MapKind_Type, dvander@195: MapKind_FunctionType, dvander@195: MapKind_StructType, dvander@209: MapKind_ArrayType, dvander@222: MapKind_ReferenceType, dvander@233: MapKind_EnumType, dvander@28: dvander@28: // Represents basic data structures. When adding to this, don't forget dvander@28: // to update Zone::initialize(), or you'll get a NULL crash trying to dvander@28: // allocate, since these maps are cached. dvander@28: MapKind_FixedArray, dvander@28: MapKind_ByteArray, dvander@28: MapKind_Code, dvander@28: MapKind_Reference, dvander@28: MapKind_Module, dvander@28: MapKind_Function, dvander@54: MapKind_String, dvander@68: MapKind_Native, dvander@53: MapKind_FreeRegion, // Special map denoting freed space. dvander@85: MapKind_EnvironmentSlotDescriptorArray, dvander@85: MapKind_Environment, dvander@146: MapKind_Descriptor, dvander@168: MapKind_Box, dvander@251: MapKind_Package, dvander@251: MapKind_List, dvander@28: dvander@147: // These do not have canonical maps. dvander@28: MapKind_Array, dvander@247: MapKind_DependentArray, dvander@147: MapKind_Struct, dvander@28: dvander@28: // These represent special Map subclasses that require special tracing. dvander@28: MapKinds_Special, dvander@85: MapKind_Meta, // (default map class) dvander@85: MapKind_MetaArray, // ArrayMap instances dvander@85: MapKind_MetaEnvironment, // EnvironmentMap instances dvander@147: MapKind_MetaStruct, // StructMap instances dvander@28: MapKinds_EndSpecial, dvander@28: dvander@28: MapKinds_Total dvander@28: }; dvander@28: dvander@28: // All garbage collected objects must inherit from GCObject. Note that using dvander@28: // virtual functions is illegal, as the |map| field would be displaced. dvander@28: class Object dvander@28: { dvander@28: Barriered map_; dvander@28: dvander@28: public: dvander@28: void init(Map *map) { dvander@28: map_ = map; dvander@28: } dvander@28: dvander@28: Map *map() { dvander@28: return map_; dvander@28: } dvander@28: inline bool is(MapKind map); dvander@28: dvander@28: inline void write(Zone *zone, Object **ptr, Object *value); dvander@52: dvander@251: static inline Object *cast(Object *obj) { dvander@251: return obj; dvander@251: } dvander@251: dvander@52: static inline size_t offsetOfMap() { danderson@91: // Clang doesn't accept offsetof here and it's not clear why... danderson@91: return reinterpret_cast(&((Object *)NULL)->map_); dvander@52: } dvander@28: }; dvander@28: dvander@28: // Maps describe the layout of GCObjects. Every GCObject requires a map. dvander@28: class Map : public Object dvander@28: { dvander@28: MapKind kind_; dvander@28: dvander@28: public: dvander@28: void setKind(MapKind kind) { dvander@28: kind_ = kind; dvander@28: } dvander@28: MapKind kind() { dvander@28: return kind_; dvander@28: } dvander@28: dvander@28: static inline Map *cast(Object *obj) { dvander@28: // Note that ArrayMap is a map, but a special one: since it is non- dvander@28: assert(obj->map()->kind() > MapKinds_Special && dvander@28: obj->map()->kind() < MapKinds_EndSpecial); dvander@28: return reinterpret_cast(obj); dvander@28: } dvander@28: }; dvander@28: dvander@28: inline bool dvander@28: Object::is(MapKind kind) dvander@28: { dvander@28: return map()->kind() == kind; dvander@28: } dvander@28: dvander@28: } dvander@28: dvander@28: #endif //_include_jitcraft_objects_h_