File: idlalloc.c

package info (click to toggle)
camlidl 1.05-7
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 872 kB
  • ctags: 1,131
  • sloc: ml: 4,894; ansic: 940; cpp: 897; makefile: 294; sh: 182
file content (144 lines) | stat: -rw-r--r-- 3,817 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/***********************************************************************/
/*                                                                     */
/*                              CamlIDL                                */
/*                                                                     */
/*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
/*                                                                     */
/*  Copyright 1999 Institut National de Recherche en Informatique et   */
/*  en Automatique.  All rights reserved.  This file is distributed    */
/*  under the terms of the GNU Library General Public License.         */
/*                                                                     */
/***********************************************************************/

/* $Id: idlalloc.c,v 1.7 2000/08/19 11:05:00 xleroy Exp $ */

/* Allocation functions and various helper functions
   for stub code generated by camlidl */

#include <string.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/callback.h>
#include "camlidlruntime.h"

/* Helper functions for conversion */

value camlidl_find_enum(int n, int *flags, int nflags, char *errmsg)
{
  int i;

  for (i = 0; i < nflags; i++) {
    if (n == flags[i]) return Val_int(i);
  }
  invalid_argument(errmsg);
  return Val_unit;              /* not reached, keeps CL happy */
}

value camlidl_alloc_flag_list(int n, int *flags, int nflags)
{
  value l = Val_int(0);
  int i;

  Begin_root(l)
    for (i = nflags - 1; i >= 0; i--)
      if (n & flags[i]) {
        value v = alloc_small(2, 0);
        Field(v, 0) = Val_int(i);
        Field(v, 1) = l;
        l = v;
        n &= ~ flags[i];
      }
  End_roots();
  return l;
}

mlsize_t camlidl_ptrarray_size(void ** array)
{
  mlsize_t i;

  for (i = 0; array[i] != NULL; i++) /*nothing*/;
  return i;
}

/* Malloc-like allocation with en masse deallocation */

void camlidl_register_allocation(camlidl_free_function free_fn,
                                 void * block,
                                 camlidl_ctx ctx)
{
  if (ctx->flags & CAMLIDL_TRANSIENT) {
    struct camlidl_block_list * l =
      stat_alloc(sizeof(struct camlidl_block_list));
    l->free_fn = free_fn;
    l->block = block;
    l->next = ctx->head;
    ctx->head = l;
  }
}

#ifdef _WIN32
static void camlidl_task_mem_free(void * ptr)
{
  CoTaskMemFree(ptr);
}
#endif

void * camlidl_malloc(size_t sz, camlidl_ctx ctx)
{
#ifdef _WIN32
  void * res = CoTaskMemAlloc(sz);
  if (res == NULL) raise_out_of_memory();
  camlidl_register_allocation(camlidl_task_mem_free, res, ctx);
#else
  void * res = stat_alloc(sz);
  camlidl_register_allocation(stat_free, res, ctx);
#endif
  return res;
}

void camlidl_free(camlidl_ctx ctx)
{
  struct camlidl_block_list * arena, * tmp;
  for (arena = ctx->head; arena != NULL; /*nothing*/) {
    arena->free_fn(arena->block);
    tmp = arena;
    arena = arena->next;
    stat_free(tmp);
  }
}

char * camlidl_malloc_string(value mlstring, camlidl_ctx ctx)
{
  mlsize_t len = string_length(mlstring);
  char * res = camlidl_malloc(len + 1, ctx);
  memcpy(res, String_val(mlstring), len + 1);
  return res;
}

/* This function is for compatibility with OCaml 2.00 and earlier */

#if defined(CAMLVERSION) && CAMLVERSION < 201

value camlidl_alloc (mlsize_t wosize, tag_t tag)
{
  value result;
  mlsize_t i;

  Assert (wosize > 0);
  if (wosize <= Max_young_wosize){
    result = alloc (wosize, tag);
    if (tag < No_scan_tag){
      for (i = 0; i < wosize; i++) Field (result, i) = 0;
    }
  }else{
    result = alloc_shr (wosize, tag);
    if (tag < No_scan_tag) memset (Bp_val (result), 0, Bsize_wsize (wosize));
    result = check_urgent_gc (result);
  }
  return result;
}

#endif