~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to erts/emulator/beam/erl_term.h

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * %CopyrightBegin%
3
 
 * 
4
 
 * Copyright Ericsson AB 2000-2009. All Rights Reserved.
5
 
 * 
 
3
 *
 
4
 * Copyright Ericsson AB 2000-2011. All Rights Reserved.
 
5
 *
6
6
 * The contents of this file are subject to the Erlang Public License,
7
7
 * Version 1.1, (the "License"); you may not use this file except in
8
8
 * compliance with the License. You should have received a copy of the
9
9
 * Erlang Public License along with this software. If not, it can be
10
10
 * retrieved online at http://www.erlang.org/.
11
 
 * 
 
11
 *
12
12
 * Software distributed under the License is distributed on an "AS IS"
13
13
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
 * the License for the specific language governing rights and limitations
15
15
 * under the License.
16
 
 * 
 
16
 *
17
17
 * %CopyrightEnd%
18
18
 */
19
19
 
20
20
#ifndef __ERL_TERM_H
21
21
#define __ERL_TERM_H
22
22
 
 
23
#include "sys.h" /* defines HALFWORD_HEAP */
 
24
 
 
25
typedef UWord Wterm;  /* Full word terms */
 
26
 
 
27
#if HALFWORD_HEAP
 
28
#  define HEAP_ON_C_STACK 0
 
29
#  if HALFWORD_ASSERT
 
30
#    ifdef ET_DEBUG
 
31
#      undef ET_DEBUG
 
32
#    endif
 
33
#    define ET_DEBUG 1
 
34
#  endif
 
35
#  if 1
 
36
#    define CHECK_POINTER_MASK 0xFFFFFFFF00000000UL
 
37
#    define COMPRESS_POINTER(APointer) ((Eterm) (UWord) (APointer))
 
38
#    define EXPAND_POINTER(AnEterm) ((UWord) (AnEterm))
 
39
#  else
 
40
#    define CHECK_POINTER_MASK 0x0UL
 
41
#    define COMPRESS_POINTER(AnUint) (AnUint)
 
42
#    define EXPAND_POINTER(APointer) (APointer)
 
43
#  endif
 
44
#else
 
45
#  define HEAP_ON_C_STACK 1
 
46
#  define CHECK_POINTER_MASK 0x0UL
 
47
#  define COMPRESS_POINTER(AnUint) (AnUint)
 
48
#  define EXPAND_POINTER(APointer) (APointer)
 
49
#endif
 
50
 
23
51
struct erl_node_; /* Declared in erl_node_tables.h */
24
52
 
25
53
/*
38
66
#endif
39
67
 
40
68
#if ET_DEBUG
41
 
#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned)
 
69
#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned);
42
70
#define _ET_APPLY(F,X)  checked_##F(X,__FILE__,__LINE__)
43
71
#else
44
72
#define _ET_DECLARE_CHECKED(TF,F,TX)
158
186
 
159
187
 
160
188
/* boxed object access methods */
 
189
#if HALFWORD_HEAP
 
190
#define _is_taggable_pointer(x)  (((UWord)(x) & (CHECK_POINTER_MASK | 0x3)) == 0)
 
191
#define _boxed_precond(x)        (is_boxed(x))
 
192
#else
 
193
#define _is_taggable_pointer(x)  (((Uint)(x) & 0x3) == 0)
 
194
#define  _boxed_precond(x)       (is_boxed(x))
 
195
#endif
161
196
#define _is_aligned(x)          (((Uint)(x) & 0x3) == 0)
162
 
#define _unchecked_make_boxed(x)        ((Uint)(x) + TAG_PRIMARY_BOXED)
163
 
_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*);
 
197
#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)
 
198
_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
164
199
#define make_boxed(x)           _ET_APPLY(make_boxed,(x))
165
200
#if 1
166
201
#define _is_not_boxed(x)        ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))
167
202
#define _unchecked_is_boxed(x)  (!_is_not_boxed((x)))
168
 
_ET_DECLARE_CHECKED(int,is_boxed,Eterm);
 
203
_ET_DECLARE_CHECKED(int,is_boxed,Eterm)
169
204
#define is_boxed(x)             _ET_APPLY(is_boxed,(x))
170
205
#else
171
206
#define is_boxed(x)             (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED)
172
207
#endif
173
 
#define _unchecked_boxed_val(x) ((Eterm*)((x) - TAG_PRIMARY_BOXED))
174
 
_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm);
 
208
#define _unchecked_boxed_val(x) ((Eterm*) EXPAND_POINTER(((x) - TAG_PRIMARY_BOXED)))
 
209
_ET_DECLARE_CHECKED(Eterm*,boxed_val,Wterm)
175
210
#define boxed_val(x)            _ET_APPLY(boxed_val,(x))
176
211
 
177
212
/* cons cell ("list") access methods */
178
 
#define _unchecked_make_list(x) ((Uint)(x) + TAG_PRIMARY_LIST)
179
 
_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*);
 
213
#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST)
 
214
_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*)
180
215
#define make_list(x)            _ET_APPLY(make_list,(x))
181
216
#if 1
182
217
#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))
183
 
_ET_DECLARE_CHECKED(int,is_not_list,Eterm);
 
218
_ET_DECLARE_CHECKED(int,is_not_list,Eterm)
184
219
#define is_not_list(x)          _ET_APPLY(is_not_list,(x))
185
220
#define is_list(x)              (!is_not_list((x)))
186
221
#else
187
222
#define is_list(x)              (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_LIST)
188
223
#define is_not_list(x)          (!is_list((x)))
189
224
#endif
190
 
#define _unchecked_list_val(x)  ((Eterm*)((x) - TAG_PRIMARY_LIST))
191
 
_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
 
225
#if HALFWORD_HEAP
 
226
#define _list_precond(x)        (is_list(x))
 
227
#else
 
228
#define _list_precond(x)       (is_list(x))
 
229
#endif
 
230
#define _unchecked_list_val(x) ((Eterm*) EXPAND_POINTER((x) - TAG_PRIMARY_LIST))
 
231
_ET_DECLARE_CHECKED(Eterm*,list_val,Wterm)
192
232
#define list_val(x)             _ET_APPLY(list_val,(x))
193
233
 
194
234
#define CONS(hp, car, cdr) \
198
238
#define CDR(x)  ((x)[1])
199
239
 
200
240
/* generic tagged pointer (boxed or list) access methods */
201
 
#define _unchecked_ptr_val(x)   ((Eterm*)((x) & ~((Uint) 0x3)))
 
241
#define _unchecked_ptr_val(x)   ((Eterm*) EXPAND_POINTER((x) & ~((Uint) 0x3)))
202
242
#define ptr_val(x)              _unchecked_ptr_val((x)) /*XXX*/
203
243
#define _unchecked_offset_ptr(x,offs)   ((x)+((offs)*sizeof(Eterm)))
204
244
#define offset_ptr(x,offs)      _unchecked_offset_ptr(x,offs)   /*XXX*/
 
245
#define _unchecked_byte_offset_ptr(x,byte_offs) ((x)+(offs))
 
246
#define byte_offset_ptr(x,offs) _unchecked_byte_offset_ptr(x,offs)  /*XXX*/
205
247
 
206
248
/* fixnum ("small") access methods */
207
 
#if defined(ARCH_64)
 
249
#if defined(ARCH_64) && !HALFWORD_HEAP
208
250
#define SMALL_BITS      (64-4)
209
251
#define SMALL_DIGITS    (17)
210
252
#else
221
263
#define is_not_valid_bit_size(x) (!is_valid_bit_size((x)))
222
264
#define MY_IS_SSMALL(x) (((Uint) (((x) >> (SMALL_BITS-1)) + 1)) < 2)
223
265
#define _unchecked_unsigned_val(x)      ((x) >> _TAG_IMMED1_SIZE)
224
 
_ET_DECLARE_CHECKED(Uint,unsigned_val,Eterm);
 
266
_ET_DECLARE_CHECKED(Uint,unsigned_val,Eterm)
225
267
#define unsigned_val(x) _ET_APPLY(unsigned_val,(x))
226
268
#define _unchecked_signed_val(x)        ((Sint)(x) >> _TAG_IMMED1_SIZE)
227
 
_ET_DECLARE_CHECKED(Sint,signed_val,Eterm);
 
269
_ET_DECLARE_CHECKED(Sint,signed_val,Eterm)
228
270
#define signed_val(x)   _ET_APPLY(signed_val,(x))
229
271
 
230
272
#if _TAG_IMMED1_SMALL == 0x0F
247
289
#define is_atom(x)      (((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_ATOM)
248
290
#define is_not_atom(x)  (!is_atom(x))
249
291
#define _unchecked_atom_val(x)  ((x) >> _TAG_IMMED2_SIZE)
250
 
_ET_DECLARE_CHECKED(Uint,atom_val,Eterm);
 
292
_ET_DECLARE_CHECKED(Uint,atom_val,Eterm)
251
293
#define atom_val(x)     _ET_APPLY(atom_val,(x))
252
294
 
253
295
/* header (arityval or thing) access methods */
254
296
#define _make_header(sz,tag)  ((Uint)(((sz) << _HEADER_ARITY_OFFS) + (tag)))
255
297
#define is_header(x)    (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_HEADER)
256
298
#define _unchecked_header_arity(x)      ((x) >> _HEADER_ARITY_OFFS)
257
 
_ET_DECLARE_CHECKED(Uint,header_arity,Eterm);
 
299
_ET_DECLARE_CHECKED(Uint,header_arity,Eterm)
258
300
#define header_arity(x) _ET_APPLY(header_arity,(x))
259
301
 
260
302
/* arityval access methods */
262
304
#define is_arity_value(x)       (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_ARITYVAL)
263
305
#define is_not_arity_value(x)   (!is_arity_value((x)))
264
306
#define _unchecked_arityval(x)  _unchecked_header_arity((x))
265
 
_ET_DECLARE_CHECKED(Uint,arityval,Eterm);
 
307
_ET_DECLARE_CHECKED(Uint,arityval,Eterm)
266
308
#define arityval(x)             _ET_APPLY(arityval,(x))
267
309
 
268
310
/* thing access methods */
269
311
#define is_thing(x)     (is_header((x)) && header_is_thing((x)))
 
312
#define is_thing_ptr(t) (is_thing((t)->header))
270
313
#define _unchecked_thing_arityval(x)    _unchecked_header_arity((x))
271
 
_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm);
 
314
_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm)
272
315
#define thing_arityval(x)       _ET_APPLY(thing_arityval,(x))
273
316
#define _unchecked_thing_subtag(x)      ((x) & _HEADER_SUBTAG_MASK)
274
 
_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm);
 
317
_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm)
275
318
#define thing_subtag(x)         _ET_APPLY(thing_subtag,(x))
276
319
 
277
320
/*
301
344
#define is_binary(x)    (is_boxed((x)) && is_binary_header(*boxed_val((x))))
302
345
#define is_not_binary(x) (!is_binary((x)))
303
346
#define _unchecked_binary_val(x) _unchecked_boxed_val((x))
304
 
_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm);
 
347
_ET_DECLARE_CHECKED(Eterm*,binary_val,Wterm)
305
348
#define binary_val(x)   _ET_APPLY(binary_val,(x))
306
349
 
307
350
/* process binaries stuff (special case of binaries) */
318
361
#define is_fun(x)               (is_boxed((x)) && is_fun_header(*boxed_val((x))))
319
362
#define is_not_fun(x)           (!is_fun((x)))
320
363
#define _unchecked_fun_val(x)   _unchecked_boxed_val((x))
321
 
_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm);
 
364
_ET_DECLARE_CHECKED(Eterm*,fun_val,Wterm)
322
365
#define fun_val(x)              _ET_APPLY(fun_val,(x))
323
366
 
324
367
/* export access methods */
326
369
#define is_export(x)     (is_boxed((x)) && is_export_header(*boxed_val((x))))
327
370
#define is_not_export(x) (!is_export((x)))
328
371
#define _unchecked_export_val(x)   _unchecked_boxed_val(x)
329
 
_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm);
 
372
_ET_DECLARE_CHECKED(Eterm*,export_val,Wterm)
330
373
#define export_val(x)   _ET_APPLY(export_val,(x))
331
374
#define is_export_header(x)     ((x) == HEADER_EXPORT)
 
375
#if HALFWORD_HEAP
 
376
#define HEADER_EXPORT   _make_header(2,_TAG_HEADER_EXPORT)
 
377
#else
332
378
#define HEADER_EXPORT   _make_header(1,_TAG_HEADER_EXPORT)
 
379
#endif
333
380
 
334
381
/* bignum access methods */
335
382
#define make_pos_bignum_header(sz)      _make_header((sz),_TAG_HEADER_POS_BIG)
336
383
#define make_neg_bignum_header(sz)      _make_header((sz),_TAG_HEADER_NEG_BIG)
337
384
#define _is_bignum_header(x)    (((x) & (_TAG_HEADER_MASK-_BIG_SIGN_BIT)) == _TAG_HEADER_POS_BIG)
338
385
#define _unchecked_bignum_header_is_neg(x)      ((x) & _BIG_SIGN_BIT)
339
 
_ET_DECLARE_CHECKED(int,bignum_header_is_neg,Eterm);
 
386
_ET_DECLARE_CHECKED(int,bignum_header_is_neg,Eterm)
340
387
#define bignum_header_is_neg(x) _ET_APPLY(bignum_header_is_neg,(x))
341
388
#define _unchecked_bignum_header_neg(x) ((x) | _BIG_SIGN_BIT)
342
 
_ET_DECLARE_CHECKED(Eterm,bignum_header_neg,Eterm);
 
389
_ET_DECLARE_CHECKED(Eterm,bignum_header_neg,Eterm)
343
390
#define bignum_header_neg(x)    _ET_APPLY(bignum_header_neg,(x))
344
391
#define _unchecked_bignum_header_arity(x)       _unchecked_header_arity((x))
345
 
_ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm);
 
392
_ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm)
346
393
#define bignum_header_arity(x)  _ET_APPLY(bignum_header_arity,(x))
347
394
#define BIG_ARITY_MAX           ((1 << 19)-1)
348
395
#define make_big(x)     make_boxed((x))
349
396
#define is_big(x)       (is_boxed((x)) && _is_bignum_header(*boxed_val((x))))
350
397
#define is_not_big(x)   (!is_big((x)))
351
398
#define _unchecked_big_val(x)   _unchecked_boxed_val((x))
352
 
_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm);
 
399
_ET_DECLARE_CHECKED(Eterm*,big_val,Wterm)
353
400
#define big_val(x)              _ET_APPLY(big_val,(x))
354
401
 
355
402
/* flonum ("float") access methods */
356
 
#ifdef ARCH_64
 
403
#if defined(ARCH_64) && !HALFWORD_HEAP
357
404
#define HEADER_FLONUM   _make_header(1,_TAG_HEADER_FLOAT)
358
405
#else
359
406
#define HEADER_FLONUM   _make_header(2,_TAG_HEADER_FLOAT)
362
409
#define is_float(x)     (is_boxed((x)) && *boxed_val((x)) == HEADER_FLONUM)
363
410
#define is_not_float(x) (!is_float(x))
364
411
#define _unchecked_float_val(x) _unchecked_boxed_val((x))
365
 
_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm);
 
412
_ET_DECLARE_CHECKED(Eterm*,float_val,Wterm)
366
413
#define float_val(x)    _ET_APPLY(float_val,(x))
367
414
 
368
415
/* Float definition for byte and word access */
374
421
    byte   fb[sizeof(ieee754_8)];
375
422
    Uint16 fs[sizeof(ieee754_8) / sizeof(Uint16)];
376
423
    Uint32 fw[sizeof(ieee754_8) / sizeof(Uint32)];
377
 
#ifdef ARCH_64
 
424
#if defined(ARCH_64) && !HALFWORD_HEAP
378
425
    Uint   fdw;
379
426
#endif
380
427
} FloatDef;
381
428
 
382
 
#ifdef ARCH_64
383
 
#define GET_DOUBLE(x, f) (f).fdw = *(float_val(x)+1)
 
429
#if defined(ARCH_64) && !HALFWORD_HEAP
 
430
 
 
431
#define FLOAT_VAL_GET_DOUBLE(fval, f) (f).fdw = *((fval)+1)
384
432
 
385
433
#define PUT_DOUBLE(f, x)  *(x) = HEADER_FLONUM, \
386
434
                          *((x)+1) = (f).fdw
387
435
#define GET_DOUBLE_DATA(p, f) (f).fdw = *((Uint *) (p))
388
436
#define PUT_DOUBLE_DATA(f,p) *((Uint *) (p)) = (f).fdw
389
437
#else
390
 
#define GET_DOUBLE(x, f) (f).fw[0] = *(float_val(x)+1), \
391
 
                         (f).fw[1] = *(float_val(x)+2)
 
438
#define FLOAT_VAL_GET_DOUBLE(fval, f) (f).fw[0] = *((fval)+1), \
 
439
                                      (f).fw[1] = *((fval)+2)
392
440
 
393
441
#define PUT_DOUBLE(f, x)  *(x) = HEADER_FLONUM, \
394
442
                          *((x)+1) = (f).fw[0], \
398
446
#define PUT_DOUBLE_DATA(f,p) *((Uint *) (p)) = (f).fw[0],\
399
447
                             *(((Uint *) (p))+1) = (f).fw[1]
400
448
#endif
 
449
 
 
450
#define GET_DOUBLE(x, f) FLOAT_VAL_GET_DOUBLE(float_val(x), f)
 
451
 
401
452
#define DOUBLE_DATA_WORDS (sizeof(ieee754_8)/sizeof(Eterm))
402
453
#define FLOAT_SIZE_OBJECT (DOUBLE_DATA_WORDS+1)
403
454
 
409
460
   (is_boxed((x)) && *boxed_val((x)) == make_arityval((a)))
410
461
#define is_not_tuple_arity(x, a) (!is_tuple_arity((x),(a)))
411
462
#define _unchecked_tuple_val(x) _unchecked_boxed_val(x)
412
 
_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm);
 
463
_ET_DECLARE_CHECKED(Eterm*,tuple_val,Wterm)
413
464
#define tuple_val(x)    _ET_APPLY(tuple_val,(x))
414
465
 
415
466
#define TUPLE0(t) \
548
599
#define is_not_internal_pid(x)  (!is_internal_pid((x)))
549
600
 
550
601
#define _unchecked_internal_pid_data(x) _GET_PID_DATA((x))
551
 
_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm);
 
602
_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm)
552
603
#define internal_pid_data(x) _ET_APPLY(internal_pid_data,(x))
553
604
 
554
605
#define _unchecked_internal_pid_node(x) erts_this_node
555
 
_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm);
 
606
_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm)
556
607
#define internal_pid_node(x) _ET_APPLY(internal_pid_node,(x))
557
608
 
558
609
#define internal_pid_number(x) _GET_PID_NUM(internal_pid_data((x)))
604
655
#define is_not_internal_port(x) (!is_internal_port(x))
605
656
 
606
657
#define _unchecked_internal_port_data(x) _GET_PORT_DATA((x))
607
 
_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm);
 
658
_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm)
608
659
#define internal_port_data(x) _ET_APPLY(internal_port_data,(x))
609
660
 
610
661
#define internal_port_number(x) _GET_PORT_NUM(internal_port_data((x)))
611
662
 
612
663
#define _unchecked_internal_port_node(x) erts_this_node
613
 
_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm);
 
664
_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm)
614
665
#define internal_port_node(x) _ET_APPLY(internal_port_node,(x))
615
666
 
616
667
#define internal_port_data_words(x) (1)
679
730
#define ERTS_MAX_REF_NUMBERS    3
680
731
#define ERTS_REF_NUMBERS        ERTS_MAX_REF_NUMBERS
681
732
 
682
 
#ifdef ARCH_64
 
733
#if defined(ARCH_64) && !HALFWORD_HEAP
683
734
#  define ERTS_REF_WORDS        (ERTS_REF_NUMBERS/2 + 1)
684
735
#  define ERTS_REF_32BIT_WORDS  (ERTS_REF_NUMBERS+1)
685
736
#else
701
752
#define make_ref_thing_header(DW) \
702
753
  _make_header((DW)+REF_THING_HEAD_SIZE-1,_TAG_HEADER_REF)
703
754
 
704
 
#ifdef ARCH_64
 
755
#if defined(ARCH_64) && !HALFWORD_HEAP
705
756
 
706
757
/*
707
758
 * Ref layout on a 64-bit little endian machine:
748
799
  ((RefThing*) internal_ref_val(x))
749
800
 
750
801
#define is_internal_ref(x) \
751
 
  (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x))))
 
802
    (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x))))
 
803
 
752
804
#define is_not_internal_ref(x) \
753
805
  (!is_internal_ref((x)))
754
806
 
755
807
#define _unchecked_internal_ref_val(x) _unchecked_boxed_val((x))
756
 
_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm);
 
808
_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Wterm)
757
809
#define internal_ref_val(x) _ET_APPLY(internal_ref_val,(x))
758
810
 
 
811
#define internal_thing_ref_data_words(t) (thing_arityval(*(Eterm*)(t)))
759
812
#define _unchecked_internal_ref_data_words(x) \
760
813
 (_unchecked_thing_arityval(*_unchecked_internal_ref_val(x)))
761
 
_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Eterm);
 
814
_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Wterm)
762
815
#define internal_ref_data_words(x) _ET_APPLY(internal_ref_data_words,(x))
763
816
 
764
 
#define _unchecked_internal_ref_data(x) (_unchecked_ref_thing_ptr(x)->data.ui32)
765
 
_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Eterm);
 
817
#define internal_thing_ref_data(thing) ((thing)->data.ui32)
 
818
#define _unchecked_internal_ref_data(x) (internal_thing_ref_data(_unchecked_ref_thing_ptr(x)))
 
819
_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Wterm)
766
820
#define internal_ref_data(x) _ET_APPLY(internal_ref_data,(x))
767
821
 
768
822
#define _unchecked_internal_ref_node(x) erts_this_node
769
 
_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm);
 
823
_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm)
770
824
#define internal_ref_node(x) _ET_APPLY(internal_ref_node,(x))
771
825
 
772
826
/*
779
833
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
780
834
 *  |A A A A A A A A A A A A A A A A A A A A A A A A A A|t t t t|0 0| Thing
781
835
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
836
 *  |E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E| ErlNode
 
837
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
782
838
 *  |N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N| Next
783
839
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
784
 
 *  |E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E| ErlNode
785
 
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
786
840
 *  |X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X| Data 0
787
841
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
788
842
 *  .                                                               .   .
793
847
 *  t : External pid thing tag  (1100)
794
848
 *  t : External port thing tag (1101)
795
849
 *  t : External ref thing tag  (1110)
796
 
 *  N : Next (external thing) pointer
 
850
 *  N : Next (off_heap) pointer
797
851
 *  E : ErlNode pointer
798
852
 *  X : Type specific data
799
853
 *
807
861
 *
808
862
 */
809
863
 
 
864
/* XXX:PaN - this structure is not perfect for halfword heap, it takes
 
865
   a lot of memory due to padding, and the array will not begin at the end of the
 
866
   structure, as otherwise expected. Be sure to access data.ui32 array and not try
 
867
   to do pointer manipulation on an Eterm * to reach the actual data...
 
868
 
 
869
   XXX:Sverk - Problem made worse by "one off-heap list" when 'next' pointer
 
870
     must align with 'next' in ProcBin, erl_fun_thing and erl_off_heap_header.
 
871
*/
810
872
typedef struct external_thing_ {
811
873
    /*                                 ----+                        */
812
874
    Eterm                   header;     /* |                        */
813
 
    struct external_thing_ *next;       /*  > External thing head   */
814
 
    struct erl_node_       *node;       /* |                        */
 
875
    struct erl_node_*       node;       /*  > External thing head   */
 
876
    struct erl_off_heap_header* next;   /* |                        */
815
877
    /*                                 ----+                        */
816
878
    union {
817
879
        Uint32              ui32[1];
839
901
#define is_external_header(x) \
840
902
  (((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID)
841
903
 
842
 
#define is_external(x) \
843
 
  (is_boxed((x)) && is_external_header(*boxed_val((x))))
 
904
#define is_external(x) (is_boxed((x)) && is_external_header(*boxed_val((x))))
 
905
 
844
906
#define is_external_pid(x) \
845
907
  (is_boxed((x)) && is_external_pid_header(*boxed_val((x))))
846
908
#define is_external_port(x) \
847
 
  (is_boxed((x)) && is_external_port_header(*boxed_val((x))))
848
 
#define is_external_ref(x) \
849
 
  (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x))))
 
909
    (is_boxed((x)) && is_external_port_header(*boxed_val((x))))
 
910
 
 
911
#define is_external_ref(x) (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x))))
850
912
 
851
913
#define _unchecked_is_external(x) \
852
914
  (_unchecked_is_boxed((x)) && is_external_header(*_unchecked_boxed_val((x))))
864
926
#define make_external_ref               make_external
865
927
 
866
928
#define _unchecked_external_val(x) _unchecked_boxed_val((x))
867
 
_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);
 
929
_ET_DECLARE_CHECKED(Eterm*,external_val,Wterm)
868
930
#define external_val(x) _ET_APPLY(external_val,(x))
869
931
 
870
932
#define external_thing_ptr(x) ((ExternalThing *) external_val((x)))
871
933
#define _unchecked_external_thing_ptr(x) \
872
934
  ((ExternalThing *) _unchecked_external_val((x)))
873
935
 
 
936
#define _unchecked_external_thing_data_words(thing) \
 
937
    (_unchecked_thing_arityval((thing)->header) + (1 - EXTERNAL_THING_HEAD_SIZE))
 
938
_ET_DECLARE_CHECKED(Uint,external_thing_data_words,ExternalThing*)
 
939
#define external_thing_data_words(thing) _ET_APPLY(external_thing_data_words,(thing))
 
940
 
874
941
#define _unchecked_external_data_words(x) \
875
 
  (_unchecked_thing_arityval(_unchecked_external_thing_ptr((x))->header) \
876
 
   + (1 - EXTERNAL_THING_HEAD_SIZE))
877
 
_ET_DECLARE_CHECKED(Uint,external_data_words,Eterm);
 
942
    _unchecked_external_thing_data_words(_unchecked_external_thing_ptr((x)))
 
943
_ET_DECLARE_CHECKED(Uint,external_data_words,Wterm)
878
944
#define external_data_words(x) _ET_APPLY(external_data_words,(x))
879
945
 
880
946
#define _unchecked_external_data(x) (_unchecked_external_thing_ptr((x))->data.ui)
885
951
 
886
952
#define _unchecked_external_pid_data_words(x) \
887
953
  _unchecked_external_data_words((x))
888
 
_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm);
 
954
_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Wterm)
889
955
#define external_pid_data_words(x) _ET_APPLY(external_pid_data_words,(x))
890
956
 
891
957
#define _unchecked_external_pid_data(x) _unchecked_external_data((x))[0]
892
 
_ET_DECLARE_CHECKED(Uint,external_pid_data,Eterm);
 
958
_ET_DECLARE_CHECKED(Uint,external_pid_data,Wterm)
893
959
#define external_pid_data(x) _ET_APPLY(external_pid_data,(x))
894
960
 
895
961
#define _unchecked_external_pid_node(x) _unchecked_external_node((x))
896
 
_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm);
 
962
_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Wterm)
897
963
#define external_pid_node(x) _ET_APPLY(external_pid_node,(x))
898
964
 
899
965
#define external_pid_number(x) _GET_PID_NUM(external_pid_data((x)))
901
967
 
902
968
#define _unchecked_external_port_data_words(x) \
903
969
  _unchecked_external_data_words((x))
904
 
_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm);
 
970
_ET_DECLARE_CHECKED(Uint,external_port_data_words,Wterm)
905
971
#define external_port_data_words(x) _ET_APPLY(external_port_data_words,(x))
906
972
 
907
973
#define _unchecked_external_port_data(x) _unchecked_external_data((x))[0]
908
 
_ET_DECLARE_CHECKED(Uint,external_port_data,Eterm);
 
974
_ET_DECLARE_CHECKED(Uint,external_port_data,Wterm)
909
975
#define external_port_data(x) _ET_APPLY(external_port_data,(x))
910
976
 
911
977
#define _unchecked_external_port_node(x) _unchecked_external_node((x))
912
 
_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Eterm);
 
978
_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Wterm)
913
979
#define external_port_node(x) _ET_APPLY(external_port_node,(x))
914
980
 
915
981
#define external_port_number(x) _GET_PORT_NUM(external_port_data((x)))
916
982
 
917
983
#define _unchecked_external_ref_data_words(x) \
918
984
  _unchecked_external_data_words((x))
919
 
_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Eterm);
 
985
_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Wterm)
920
986
#define external_ref_data_words(x) _ET_APPLY(external_ref_data_words,(x))
 
987
#define external_thing_ref_data_words(thing) external_thing_data_words(thing)
921
988
 
922
989
#define _unchecked_external_ref_data(x) (_unchecked_external_thing_ptr((x))->data.ui32)
923
 
_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Eterm);
 
990
_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Wterm)
924
991
#define external_ref_data(x) _ET_APPLY(external_ref_data,(x))
 
992
#define external_thing_ref_data(thing) ((thing)->data.ui32)
925
993
 
926
994
#define _unchecked_external_ref_node(x) _unchecked_external_node((x))
927
 
_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm);
 
995
_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
928
996
#define external_ref_node(x) _ET_APPLY(external_ref_node,(x))
929
997
 
930
998
/* number tests */
944
1012
#error "fix yer arch, like"
945
1013
#endif
946
1014
 
947
 
#define _unchecked_make_cp(x)   ((Eterm)(x))
948
 
_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*);
 
1015
#define _unchecked_make_cp(x)   ((Eterm) COMPRESS_POINTER(x))
 
1016
_ET_DECLARE_CHECKED(Eterm,make_cp,BeamInstr*)
949
1017
#define make_cp(x)      _ET_APPLY(make_cp,(x))
950
1018
 
951
1019
#define is_not_CP(x)    ((x) & _CPMASK)
952
1020
#define is_CP(x)        (!is_not_CP(x))
953
1021
 
954
 
#define _unchecked_cp_val(x)    ((Uint*)(x))
955
 
_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm);
 
1022
#define _unchecked_cp_val(x)    ((BeamInstr*) EXPAND_POINTER(x))
 
1023
_ET_DECLARE_CHECKED(BeamInstr*,cp_val,Eterm)
956
1024
#define cp_val(x)       _ET_APPLY(cp_val,(x))
957
1025
 
958
1026
#define make_catch(x)   (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH)
959
1027
#define is_catch(x)     (((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_CATCH)
960
1028
#define is_not_catch(x) (!is_catch(x))
961
1029
#define _unchecked_catch_val(x) ((x) >> _TAG_IMMED2_SIZE)
962
 
_ET_DECLARE_CHECKED(Uint,catch_val,Eterm);
 
1030
_ET_DECLARE_CHECKED(Uint,catch_val,Eterm)
963
1031
#define catch_val(x)    _ET_APPLY(catch_val,(x))
964
1032
 
965
1033
#define make_blank(X)   ((X) = NIL)
989
1057
#define _is_yreg(x)     (beam_reg_tag(x) == Y_REG_DEF)
990
1058
 
991
1059
#define _unchecked_x_reg_offset(R)      ((R) - X_REG_DEF)
992
 
_ET_DECLARE_CHECKED(Uint,x_reg_offset,Uint);
 
1060
_ET_DECLARE_CHECKED(Uint,x_reg_offset,Uint)
993
1061
#define x_reg_offset(R) _ET_APPLY(x_reg_offset,(R))
994
1062
 
995
1063
#define _unchecked_y_reg_offset(R)      ((R) - Y_REG_DEF)
996
 
_ET_DECLARE_CHECKED(Uint,y_reg_offset,Uint);
 
1064
_ET_DECLARE_CHECKED(Uint,y_reg_offset,Uint)
997
1065
#define y_reg_offset(R) _ET_APPLY(y_reg_offset,(R))
998
1066
 
999
1067
#define reg_index(R) ((R) / sizeof(Eterm))
1000
1068
 
1001
1069
#define _unchecked_x_reg_index(R)       ((R) >> 2)
1002
 
_ET_DECLARE_CHECKED(Uint,x_reg_index,Uint);
 
1070
_ET_DECLARE_CHECKED(Uint,x_reg_index,Uint)
1003
1071
#define x_reg_index(R)  _ET_APPLY(x_reg_index,(R))
1004
1072
 
1005
1073
#define _unchecked_y_reg_index(R)       ((R) >> 2)
1006
 
_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint);
 
1074
_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint)
1007
1075
#define y_reg_index(R)  _ET_APPLY(y_reg_index,(R))
1008
1076
 
1009
1077
/*
1033
1101
#define SMALL_DEF               0xf
1034
1102
 
1035
1103
#if ET_DEBUG
1036
 
extern unsigned tag_val_def_debug(Eterm, const char*, unsigned);
 
1104
extern unsigned tag_val_def_debug(Wterm, const char*, unsigned);
1037
1105
#define tag_val_def(x)  tag_val_def_debug((x),__FILE__,__LINE__)
1038
1106
#else
1039
 
extern unsigned tag_val_def(Eterm);
 
1107
extern unsigned tag_val_def(Wterm);
1040
1108
#endif
1041
1109
#define not_eq_tags(X,Y)        (tag_val_def((X)) ^ tag_val_def((Y)))
1042
1110
 
1052
1120
#define FLOAT_BIG       _NUMBER_CODE(FLOAT_DEF,BIG_DEF)
1053
1121
#define FLOAT_FLOAT     _NUMBER_CODE(FLOAT_DEF,FLOAT_DEF)
1054
1122
 
 
1123
#if HALFWORD_HEAP
 
1124
#define ptr2rel(PTR,BASE) ((Eterm*)((char*)(PTR) - (char*)(BASE)))
 
1125
#define rterm2wterm(REL,BASE) ((Wterm)(REL) + (Wterm)(BASE))
 
1126
 
 
1127
#else /* HALFWORD_HEAP */
 
1128
 
 
1129
#define ptr2rel(PTR,BASE) (PTR)
 
1130
#define rterm2wterm(REL,BASE) (REL)
 
1131
 
 
1132
#endif /* !HALFWORD_HEAP */
 
1133
 
 
1134
#define make_list_rel(PTR, BASE) make_list(ptr2rel(PTR,BASE))
 
1135
#define make_boxed_rel(PTR, BASE) make_boxed(ptr2rel(PTR,BASE))
 
1136
#define make_fun_rel make_boxed_rel
 
1137
#define make_binary_rel make_boxed_rel
 
1138
#define make_tuple_rel make_boxed_rel
 
1139
#define make_external_rel make_boxed_rel
 
1140
#define make_internal_ref_rel make_boxed_rel
 
1141
 
 
1142
#define binary_val_rel(RTERM, BASE) binary_val(rterm2wterm(RTERM, BASE))
 
1143
#define list_val_rel(RTERM, BASE) list_val(rterm2wterm(RTERM, BASE))
 
1144
#define boxed_val_rel(RTERM, BASE) boxed_val(rterm2wterm(RTERM, BASE))
 
1145
#define tuple_val_rel(RTERM, BASE) tuple_val(rterm2wterm(RTERM, BASE))
 
1146
#define export_val_rel(RTERM, BASE) export_val(rterm2wterm(RTERM, BASE))
 
1147
#define fun_val_rel(RTERM, BASE) fun_val(rterm2wterm(RTERM, BASE))
 
1148
#define big_val_rel(RTERM,BASE) big_val(rterm2wterm(RTERM,BASE))
 
1149
#define float_val_rel(RTERM,BASE) float_val(rterm2wterm(RTERM,BASE))
 
1150
#define internal_ref_val_rel(RTERM,BASE) internal_ref_val(rterm2wterm(RTERM,BASE))
 
1151
 
 
1152
#define external_thing_ptr_rel(RTERM, BASE) external_thing_ptr(rterm2wterm(RTERM, BASE))
 
1153
#define external_data_words_rel(RTERM,BASE) external_data_words(rterm2wterm(RTERM,BASE))
 
1154
 
 
1155
#define external_port_node_rel(RTERM,BASE) external_port_node(rterm2wterm(RTERM,BASE))
 
1156
#define external_port_data_rel(RTERM,BASE) external_port_data(rterm2wterm(RTERM,BASE))
 
1157
 
 
1158
#define is_external_pid_rel(RTERM,BASE) is_external_pid(rterm2wterm(RTERM,BASE))
 
1159
#define external_pid_node_rel(RTERM,BASE) external_pid_node(rterm2wterm(RTERM,BASE))
 
1160
#define external_pid_data_rel(RTERM,BASE) external_pid_data(rterm2wterm(RTERM,BASE))
 
1161
 
 
1162
#define is_binary_rel(RTERM,BASE) is_binary(rterm2wterm(RTERM,BASE))
 
1163
#define is_float_rel(RTERM,BASE) is_float(rterm2wterm(RTERM,BASE))
 
1164
#define is_fun_rel(RTERM,BASE) is_fun(rterm2wterm(RTERM,BASE))
 
1165
#define is_big_rel(RTERM,BASE) is_big(rterm2wterm(RTERM,BASE))
 
1166
#define is_export_rel(RTERM,BASE) is_export(rterm2wterm(RTERM,BASE))
 
1167
#define is_tuple_rel(RTERM,BASE) is_tuple(rterm2wterm(RTERM,BASE))
 
1168
 
 
1169
#define GET_DOUBLE_REL(RTERM, f, BASE) GET_DOUBLE(rterm2wterm(RTERM,BASE), f)
 
1170
 
 
1171
#define ref_thing_ptr_rel(RTERM,BASE) ref_thing_ptr(rterm2wterm(RTERM,BASE))
 
1172
#define is_internal_ref_rel(RTERM,BASE) is_internal_ref(rterm2wterm(RTERM,BASE))
 
1173
#define is_external_rel(RTERM,BASE) is_external(rterm2wterm(RTERM,BASE))
 
1174
#define is_external_port_rel(RTERM,BASE) is_external_port(rterm2wterm(RTERM,BASE))
 
1175
#define is_external_ref_rel(RTERM,BASE) is_external_ref(rterm2wterm(RTERM,BASE))
 
1176
 
 
1177
#define external_node_rel(RTERM,BASE) external_node(rterm2wterm(RTERM,BASE))
 
1178
 
 
1179
 
 
1180
#if HALFWORD_HEAP
 
1181
ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base);
 
1182
 
 
1183
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
 
1184
ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base)
 
1185
{
 
1186
    /* If bases differ, assume a and b are on different "heaps",
 
1187
       ie can only be same if immed */
 
1188
    ASSERT(a_base == b_base || is_immed(a) || is_immed(b)
 
1189
           || rterm2wterm(a,a_base) != rterm2wterm(b,b_base));
 
1190
 
 
1191
    return a == b && (a_base == b_base || is_immed(a));
 
1192
}
 
1193
#endif
 
1194
 
 
1195
#else /* !HALFWORD_HEAP */
 
1196
#define is_same(A,A_BASE,B,B_BASE) ((A)==(B))
 
1197
#endif
 
1198
 
1055
1199
#endif  /* __ERL_TERM_H */
1056
1200