Add test for |do|.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
19 #ifndef _include_jc_types_h_
20 #define _include_jc_types_h_
24 #include "FixedArray.h"
25 #include "compiler/Token.h"
33 #define MAX_ARRAY_DEPTH 5
37 // A boolean type semantically represents 0 or 1. As an optimization, its
38 // internal storage type is the same as int32, and any non-zero value
39 // compares positively to "true".
42 // A character is an arbitrary 8-bit value. Characters are not supported
43 // as a normal storage class; they may only be used for arrays. When read
44 // from an array, they are immediately sign extended to 32 bits. Integers
45 // stored into an char array are truncated to 8 bits.
46 PrimitiveType_Char, // signed, 8-bit character
48 // Enumerations and untyped variables are stored as signed, 32-bit integers.
51 // Floating point values are 32-bit IEEE-754 floats. This is required ro
52 // SourcePawn 1 compatibility.
55 // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
56 // on 64-bit systems), and does not exist in language semantics.
62 class Type : public Object
66 // A primitive is a plain-old-data type.
69 // An array is a fixed-length vector of any other type.
73 // A reference type may only be specified on parameters, and
74 // references may only be computed to primitives or enums.
77 // A function type encapsulates a function signature.
80 // Void is an internal type used to specify that a function returns no
84 // Enums are plain-old-data with int32 storage. They allow for extra
85 // type checking that would not be possible with integers.
88 // Structs are composite records that may contain primitives, arrays,
89 // functions, enums, and other structs.
92 // Unchecked is a magic type that has implicit, bitwise coercion to
93 // int32, float, bool, or an enum.
103 static const int DYNAMIC_ARRAY_SIZE = -1;
105 static Type *NewVoid(Zone *zone);
106 static Type *NewUnchecked(Zone *zone);
107 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
108 static Type *NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst);
109 static Type *NewExternalArray(Zone *zone, Handle<Type> contained);
110 static Type *NewReference(Zone *zone, Handle<Type> contained, bool isConst);
111 static Type *NewEnum(Zone *zone, Handle<String> name);
113 static bool Compare(Type *left, Type *right);
115 static Type *cast(Object *obj) {
117 obj->is(MapKind_Type) ||
118 obj->is(MapKind_FunctionType) ||
119 obj->is(MapKind_StructType));
124 return kind() == PRIMITIVE;
127 return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
130 return kind() == REFERENCE;
133 return kind() == FUNCTION;
136 return kind() == VOID;
139 return kind() == UNCHECKED;
142 return kind() == STRUCT;
144 PrimitiveType primitive() {
145 assert(isPrimitive());
149 return isPrimitive() || isEnum() || isUnchecked();
151 PrimitiveType pod() {
154 ? (primitive() == PrimitiveType_Bool)
155 ? PrimitiveType_Int32
157 : PrimitiveType_Int32;
160 assert(isArray() || isReference());
161 return Type::cast(contained_);
163 bool isFixedLength() {
165 return elements_ > 0;
167 unsigned fixedLength() {
168 assert(isFixedLength());
175 bool hasInlineElements() {
178 // We don't allocate traceable elements inline, since there's no
179 // point to the optimization; we're going to be allocating lots of
180 // objects anyway (in theory).
181 return isFixedLength() && !contained()->isTraceable();
185 Type *temp = contained();
186 while (temp->isArray())
187 temp = temp->contained();
191 return isPrimitive() && primitive() == PrimitiveType_Float;
194 return isPrimitive() && primitive() == PrimitiveType_Int32;
196 bool isInt32OrEnum() {
197 return isInt32() || isEnum();
200 return isPrimitive() && primitive() == PrimitiveType_Bool;
204 contained()->isPrimitive() &&
205 contained()->primitive() == PrimitiveType_Char;
207 bool isExternalArray() {
208 return kind() == EXTERNAL_ARRAY;
211 return !isPrimitive();
214 assert(isPrimitive() ||
220 return kind() == ENUM;
224 assert(isEnum() || isStruct());
232 void setNewMap(void *p) {
237 static inline size_t offsetOfContained() {
238 return OFFSETOF(Type, contained_);
240 static inline size_t offsetOfName() {
241 return OFFSETOF(Type, name_);
243 // End GC Descriptor.
247 PrimitiveType primitive_;
249 // Primitives, arrays, and references.
256 // Arrays and references only.
257 Barriered<Type> contained_;
259 // Enums and structs only.
260 Barriered<String> name_;
263 class StructType : public Type
266 static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
268 FixedArray *fields() {
272 Descriptor *lookupField(Handle<String> name, unsigned *index = NULL);
274 // Objects of this type can be created with this cached map.
275 StructMap *newMap() {
278 void setNewMap(StructMap *map) {
284 static inline size_t offsetOfFields() {
285 return OFFSETOF(StructType, fields_);
287 static inline size_t offsetOfNewMap() {
288 return OFFSETOF(StructType, newMap_);
290 // End GC Descriptor.
292 static StructType *cast(Object *obj) {
293 assert(!obj || obj->is(MapKind_StructType));
294 return (StructType *)obj;
299 Barriered<FixedArray> fields_;
300 Barriered<StructMap> newMap_;
303 class FunctionType : public Type
306 static FunctionType *New(Zone *zone, TokenKind kind);
308 Type *parameterAt(size_t i) {
309 return Type::cast(parameters()->at(i));
312 assert(isFunction());
315 FixedArray *parameters() {
316 assert(isFunction());
319 FixedArray *defaults() {
320 assert(isFunction());
324 return token_ == TOK_NATIVE;
327 return token_ == TOK_FORWARD;
329 bool isNativeVariadic() {
331 return variadicNative_;
333 void setReturnType(Handle<Type> returnType) {
334 assert(!returnType_);
335 returnType_ = returnType;
337 void setParameterTypes(Handle<FixedArray> types) {
338 assert(!parameters_);
346 static inline size_t offsetOfReturnType() {
347 return OFFSETOF(FunctionType, returnType_);
349 static inline size_t offsetOfParameters() {
350 return OFFSETOF(FunctionType, parameters_);
352 static inline size_t offsetOfDefaults() {
353 return OFFSETOF(FunctionType, defaults_);
355 // End GC Descriptor.
357 static FunctionType *cast(Object *obj) {
358 assert(!obj || obj->is(MapKind_FunctionType));
359 return (FunctionType *)obj;
364 Barriered<Type> returnType_;
365 Barriered<FixedArray> parameters_;
366 Barriered<FixedArray> defaults_;
368 bool variadicNative_;
380 static BoxedPrimitive Int(int i) {
382 b.type_ = PrimitiveType_Int32;
386 static BoxedPrimitive Float(float f) {
388 b.type_ = PrimitiveType_Float;
393 PrimitiveType type() const {
397 assert(type() == PrimitiveType_Int32);
400 float toFloat() const {
401 assert(type() == PrimitiveType_Float);
406 const char *GetTypeName(Type *type);
410 #endif // _include_jc_types_h_