Re-implement array assignment.
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"
34 #define MAX_ARRAY_DEPTH 5
38 // A boolean type semantically represents 0 or 1. As an optimization, its
39 // internal storage type is the same as int32, and any non-zero value
40 // compares positively to "true".
43 // A character is an arbitrary 8-bit value. Characters are not supported
44 // as a normal storage class; they may only be used for arrays. When read
45 // from an array, they are immediately sign extended to 32 bits. Integers
46 // stored into an char array are truncated to 8 bits.
47 PrimitiveType_Char, // signed, 8-bit character
49 // Enumerations and untyped variables are stored as signed, 32-bit integers.
52 // Floating point values are 32-bit IEEE-754 floats. This is required ro
53 // SourcePawn 1 compatibility.
56 // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
57 // on 64-bit systems), and does not exist in language semantics.
63 class Type : public Object
67 // A primitive is a plain-old-data type.
70 // Void is an internal type used to specify that a function returns no
74 // Enums are plain-old-data with int32 storage. They allow for extra
75 // type checking that would not be possible with integers.
78 // Unchecked is a magic type that has implicit, bitwise coercion to
79 // int32, float, bool, or an enum.
82 // ------ Add traceable types below -------
84 // An immutable type that is a primitive in terms of language
85 // semantics, but gets a special type here to make internal
89 // An array is a fixed-length vector of any other type.
93 // A reference type may only be specified on parameters, and
94 // references may only be computed to primitives or enums.
97 // A function type encapsulates a function signature.
100 // Structs are composite records that may contain primitives, arrays,
101 // functions, enums, and other structs.
111 static Type *NewVoid(Zone *zone);
112 static Type *NewUnchecked(Zone *zone);
113 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
114 static Type *NewString(Zone *zone);
116 static Type *cast(Object *obj) {
118 obj->is(MapKind_Type) ||
119 obj->is(MapKind_FunctionType) ||
120 obj->is(MapKind_StructType) ||
121 obj->is(MapKind_ArrayType) ||
122 obj->is(MapKind_ReferenceType) ||
123 obj->is(MapKind_EnumType));
128 return kind() == PRIMITIVE;
131 return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
134 return kind() == REFERENCE;
137 return kind() == FUNCTION;
140 return kind() == VOID;
143 return kind() == UNCHECKED;
146 return kind() == STRUCT;
148 PrimitiveType primitive() {
149 assert(isPrimitive());
153 return (isPrimitive() && !isString()) || isEnum() || isUnchecked();
155 PrimitiveType pod() {
158 ? (primitive() == PrimitiveType_Bool)
159 ? PrimitiveType_Int32
161 : PrimitiveType_Int32;
164 return isPrimitive() && primitive() == PrimitiveType_Char;
167 return isPrimitive() && primitive() == PrimitiveType_Float;
170 return isPrimitive() && primitive() == PrimitiveType_Int32;
172 bool isInt32OrEnum() {
173 return isInt32() || isEnum();
176 return isPrimitive() && primitive() == PrimitiveType_Bool;
179 return kind() == STRING;
181 bool isExternalArray() {
182 return kind() == EXTERNAL_ARRAY;
185 return kind_ >= STRING;
188 assert(isPrimitive() ||
194 return kind() == ENUM;
199 PrimitiveType primitive_;
201 // Primitives, arrays, and references.
205 class EnumType : public Type
208 static EnumType *New(Zone *Zone, Handle<String> name);
215 static inline size_t offsetOfName() {
216 return OFFSETOF(EnumType, name_);
218 // End GC Descriptor.
220 static EnumType *cast(Object *obj) {
221 assert(!obj || obj->is(MapKind_EnumType));
222 return (EnumType *)obj;
226 Barriered<String> name_;
229 class ReferenceType : public Type
232 static ReferenceType *New(Zone *zone, Handle<Type> contained);
239 static inline size_t offsetOfContained() {
240 return OFFSETOF(ReferenceType, contained_);
242 // End GC Descriptor.
244 static ReferenceType *cast(Object *obj) {
245 assert(!obj || obj->is(MapKind_ReferenceType));
246 return (ReferenceType *)obj;
250 Barriered<Type> contained_;
253 class ArrayType : public Type
256 static const int DYNAMIC_ARRAY_SIZE = -1;
258 static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
259 static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
262 Type *temp = contained();
263 while (temp->isArray())
264 temp = ArrayType::cast(temp)->contained();
271 bool isFixedLength() {
272 return elements_ > 0;
275 return contained()->isPrimitive() &&
276 contained()->primitive() == PrimitiveType_Char;
278 unsigned fixedLength() {
279 assert(isFixedLength());
285 bool hasInlineElements() {
286 // We don't allocate traceable elements inline, since there's no
287 // point to the optimization; we're going to be allocating lots of
288 // objects anyway (in theory).
289 return isFixedLength() && !contained()->isTraceable();
292 // Arrays of this type can be created with this cached map.
296 void setNewMap(ArrayMap *map) {
302 static inline size_t offsetOfContained() {
303 return OFFSETOF(ArrayType, contained_);
305 static inline size_t offsetOfNewMap() {
306 return OFFSETOF(ArrayType, newMap_);
308 // End GC Descriptor.
310 static ArrayType *cast(Object *obj) {
311 assert(!obj || obj->is(MapKind_ArrayType));
312 return (ArrayType *)obj;
318 Barriered<Type> contained_;
319 Barriered<ArrayMap> newMap_;
322 class StructType : public Type
325 static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
327 FixedArray *fields() {
331 Descriptor *lookupField(Handle<String> name, unsigned *index = NULL);
333 // Objects of this type can be created with this cached map.
334 StructMap *newMap() {
337 void setNewMap(StructMap *map) {
347 static inline size_t offsetOfFields() {
348 return OFFSETOF(StructType, fields_);
350 static inline size_t offsetOfNewMap() {
351 return OFFSETOF(StructType, newMap_);
353 static inline size_t offsetOfName() {
354 return OFFSETOF(StructType, name_);
356 // End GC Descriptor.
358 static StructType *cast(Object *obj) {
359 assert(!obj || obj->is(MapKind_StructType));
360 return (StructType *)obj;
365 Barriered<FixedArray> fields_;
366 Barriered<StructMap> newMap_;
367 Barriered<String> name_;
370 class FunctionType : public Type
373 static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
375 Type *parameterAt(size_t i) {
376 return Type::cast(parameters()->at(i));
379 assert(isFunction());
382 FixedArray *parameters() {
383 assert(isFunction());
386 FixedArray *defaults() {
387 assert(isFunction());
391 return token_ == TOK_NATIVE;
394 return token_ == TOK_FORWARD;
396 bool isNativeVariadic() {
398 return variadicNative_;
400 void setReturnType(Handle<Type> returnType) {
401 assert(!returnType_);
402 returnType_ = returnType;
404 void setParameterTypes(Handle<FixedArray> types) {
405 assert(!parameters_);
416 static inline size_t offsetOfReturnType() {
417 return OFFSETOF(FunctionType, returnType_);
419 static inline size_t offsetOfParameters() {
420 return OFFSETOF(FunctionType, parameters_);
422 static inline size_t offsetOfDefaults() {
423 return OFFSETOF(FunctionType, defaults_);
425 static inline size_t offsetOfName() {
426 return OFFSETOF(FunctionType, name_);
428 // End GC Descriptor.
430 static FunctionType *cast(Object *obj) {
431 assert(!obj || obj->is(MapKind_FunctionType));
432 return (FunctionType *)obj;
437 Barriered<Type> returnType_;
438 Barriered<FixedArray> parameters_;
439 Barriered<FixedArray> defaults_;
440 Barriered<String> name_;
442 bool variadicNative_;
454 static BoxedPrimitive Int(int i) {
456 b.type_ = PrimitiveType_Int32;
460 static BoxedPrimitive Float(float f) {
462 b.type_ = PrimitiveType_Float;
467 PrimitiveType type() const {
471 assert(type() == PrimitiveType_Int32);
474 float toFloat() const {
475 assert(type() == PrimitiveType_Float);
480 const char *GetTypeName(Type *type);
484 #endif // _include_jc_types_h_