1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 // This file is included into eval.h
47 * Simple string. Always allocated inside an Allocator heap. Always NUL-terminated
48 * for debugging convenience.
53 uint32_t length
; // number of chars excluding NUL
54 uint32_t hash
; // hash code
55 uint32_t ident
; // ~0 or the index in the string pool
56 Str
* next
; // next in hashtable bucket
57 wchar s
[1]; // actually longer
60 uint32_t hashString(const wchar
* chars
, uint32_t nchars
);
61 uint32_t lenU30(uint32_t val
);
62 uint32_t utf8length(Str
* str
);
63 uint8_t* emitU16(uint8_t* out
, uint16_t val
);
64 uint8_t* emitU32(uint8_t* out
, uint32_t val
);
65 uint8_t* emitU30(uint8_t* out
, uint32_t val
);
66 uint8_t* emitS32(uint8_t* out
, int32_t val
);
67 uint8_t* emitS24(uint8_t* out
, int32_t val
);
68 uint8_t* emitDouble(uint8_t* out
, double d
);
69 uint8_t* emitUtf8(uint8_t* out
, Str
* s
);
71 int32_t readS24(uint8_t* in
);
73 void formatUtf8(char* buf
, size_t bufsiz
, const wchar
* s
);
76 // Get up to limit-1 characters from s into buf, chop high bits, NUL-terminate, return buf
77 char* getn(char* buf
, const Str
* s
, size_t limit
);
80 inline uint32_t min(uint32_t a
, uint32_t b
) { return a
< b
? a
: b
; }
81 inline uint32_t max(uint32_t a
, uint32_t b
) { return a
> b
? a
: b
; }
83 inline int32_t min(int32_t a
, int32_t b
) { return a
< b
? a
: b
; }
84 inline int32_t max(int32_t a
, int32_t b
) { return a
> b
? a
: b
; }
87 * Convenience wrapper for accumulating string values for
88 * identifiers, strings, regular expressions, xml text.
97 wchar data
[chunksize
];
101 class StringBuilder
{
103 StringBuilder(Compiler
* compiler
);
107 void append(Str
* other
);
108 void append(const char* other
);
109 void append(StringBuilder
* other
);
110 void append(const wchar
* ptr
, const wchar
* lim
);
114 char *chardata(); // NUL-terminated array, freshly allocated on every call. Data are chopped to 7 bits.
117 void append(SBChunk
* other
);
118 wchar
* copyInto(wchar
* buf
, SBChunk
* c
);
119 char* copyInto(char* buf
, SBChunk
* c
);
123 Allocator
* const allocator
;
124 SBChunk
* chunk
; // current chunk
125 uint32_t nextchar
; // next free char in chunk
126 uint32_t len
; // total length
131 * Bump-a-pointer allocator.
133 * Used for all allocation by the run-time compiler except the allocation for the
134 * final ABC bytevector.
136 * FIXME: The allocator is a little prone to internal fragmentation on the
137 * block level. This is because fairly large blocks at the end of a segment
138 * may be lost if a large request comes in and causes a new segment to be allocated.
139 * We can fix that with a simple free list of large blocks, if it turns out
140 * to be a problem in practice, or we can make the growth increment relatively
145 Allocator(Compiler
* compiler
);
148 void* alloc(size_t nbytes
);
150 Compiler
* const compiler
;
151 SBChunk
* free_sbchunks
; // shared among all StringBuilders working off this allocator
154 void* allocSlow(size_t nbytes
);
155 void refill(size_t nbytes
);
160 #ifndef AVMPLUS_64BIT
166 Chunk
* current_chunk
;
173 * Efficient accumulator for sequence of bytes. check() checks for available
174 * space and returns a valid output pointer for that many bytes; the number
175 * of bytes requested may be larger than 'increment' but this should be the
176 * exception, not the rule. 'increment' is the allocation quantum from the
177 * underlying allocator; it should be a smallish fraction of the underlying
178 * allocator's quantum.
180 * size() returns the number of bytes currently in the buffer. serialize()
181 * copies those into a sequential array starting at b.
185 ByteBuffer(Allocator
* allocator
, uint32_t increment
=100);
187 uint32_t size() const;
188 void serialize(uint8_t* b
) const;
190 void emitU8(uint8_t val
);
191 void emitS8(int8_t val
);
192 void emitU16(uint16_t val
);
193 void emitU32(uint32_t val
);
194 void emitU30(uint32_t val
);
195 void emitS32(int32_t val
);
196 void emitS24(int32_t val
);
197 void emitDouble(double d
);
198 void emitUtf8(uint32_t nbytes
, Str
* s
);
205 uint8_t start
[1]; // actually longer
208 Allocator
* const allocator
;
209 const uint32_t increment
;
214 uint32_t size_rest
; // collected size of the chunks not including last
216 void makeRoom(uint32_t nbytes
);
217 void makeRoomSlow(uint32_t nbytes
);
220 // This is useful if an allocator is in scope with the name "allocator"
221 #define ALLOC(type, args) \
222 new (allocator->alloc(sizeof(type))) type args
224 template<class T
> class Seq
{
226 Seq(T hd
, Seq
<T
>* tl
=NULL
) : hd(hd
), tl(tl
) {}
231 template<class T
> class SeqBuilder
{
233 SeqBuilder(Allocator
* allocator
) : allocator(allocator
), items(NULL
), last(NULL
) {}
235 void addAtEnd(T item
);
239 Allocator
* allocator
;