~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/lua/src/lbitlib.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $
 
3
** Standard library for bitwise operations
 
4
** See Copyright Notice in lua.h
 
5
*/
 
6
 
 
7
#define lbitlib_c
 
8
#define LUA_LIB
 
9
 
 
10
#include "lua.h"
 
11
 
 
12
#include "lauxlib.h"
 
13
#include "lualib.h"
 
14
 
 
15
 
 
16
/* number of bits to consider in a number */
 
17
#if !defined(LUA_NBITS)
 
18
#define LUA_NBITS       32
 
19
#endif
 
20
 
 
21
 
 
22
#define ALLONES         (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
 
23
 
 
24
/* macro to trim extra bits */
 
25
#define trim(x)         ((x) & ALLONES)
 
26
 
 
27
 
 
28
/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
 
29
#define mask(n)         (~((ALLONES << 1) << ((n) - 1)))
 
30
 
 
31
 
 
32
typedef lua_Unsigned b_uint;
 
33
 
 
34
 
 
35
 
 
36
static b_uint andaux (lua_State *L) {
 
37
  int i, n = lua_gettop(L);
 
38
  b_uint r = ~(b_uint)0;
 
39
  for (i = 1; i <= n; i++)
 
40
    r &= luaL_checkunsigned(L, i);
 
41
  return trim(r);
 
42
}
 
43
 
 
44
 
 
45
static int b_and (lua_State *L) {
 
46
  b_uint r = andaux(L);
 
47
  lua_pushunsigned(L, r);
 
48
  return 1;
 
49
}
 
50
 
 
51
 
 
52
static int b_test (lua_State *L) {
 
53
  b_uint r = andaux(L);
 
54
  lua_pushboolean(L, r != 0);
 
55
  return 1;
 
56
}
 
57
 
 
58
 
 
59
static int b_or (lua_State *L) {
 
60
  int i, n = lua_gettop(L);
 
61
  b_uint r = 0;
 
62
  for (i = 1; i <= n; i++)
 
63
    r |= luaL_checkunsigned(L, i);
 
64
  lua_pushunsigned(L, trim(r));
 
65
  return 1;
 
66
}
 
67
 
 
68
 
 
69
static int b_xor (lua_State *L) {
 
70
  int i, n = lua_gettop(L);
 
71
  b_uint r = 0;
 
72
  for (i = 1; i <= n; i++)
 
73
    r ^= luaL_checkunsigned(L, i);
 
74
  lua_pushunsigned(L, trim(r));
 
75
  return 1;
 
76
}
 
77
 
 
78
 
 
79
static int b_not (lua_State *L) {
 
80
  b_uint r = ~luaL_checkunsigned(L, 1);
 
81
  lua_pushunsigned(L, trim(r));
 
82
  return 1;
 
83
}
 
84
 
 
85
 
 
86
static int b_shift (lua_State *L, b_uint r, int i) {
 
87
  if (i < 0) {  /* shift right? */
 
88
    i = -i;
 
89
    r = trim(r);
 
90
    if (i >= LUA_NBITS) r = 0;
 
91
    else r >>= i;
 
92
  }
 
93
  else {  /* shift left */
 
94
    if (i >= LUA_NBITS) r = 0;
 
95
    else r <<= i;
 
96
    r = trim(r);
 
97
  }
 
98
  lua_pushunsigned(L, r);
 
99
  return 1;
 
100
}
 
101
 
 
102
 
 
103
static int b_lshift (lua_State *L) {
 
104
  return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
 
105
}
 
106
 
 
107
 
 
108
static int b_rshift (lua_State *L) {
 
109
  return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
 
110
}
 
111
 
 
112
 
 
113
static int b_arshift (lua_State *L) {
 
114
  b_uint r = luaL_checkunsigned(L, 1);
 
115
  int i = luaL_checkint(L, 2);
 
116
  if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
 
117
    return b_shift(L, r, -i);
 
118
  else {  /* arithmetic shift for 'negative' number */
 
119
    if (i >= LUA_NBITS) r = ALLONES;
 
120
    else
 
121
      r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
 
122
    lua_pushunsigned(L, r);
 
123
    return 1;
 
124
  }
 
125
}
 
126
 
 
127
 
 
128
static int b_rot (lua_State *L, int i) {
 
129
  b_uint r = luaL_checkunsigned(L, 1);
 
130
  i &= (LUA_NBITS - 1);  /* i = i % NBITS */
 
131
  r = trim(r);
 
132
  r = (r << i) | (r >> (LUA_NBITS - i));
 
133
  lua_pushunsigned(L, trim(r));
 
134
  return 1;
 
135
}
 
136
 
 
137
 
 
138
static int b_lrot (lua_State *L) {
 
139
  return b_rot(L, luaL_checkint(L, 2));
 
140
}
 
141
 
 
142
 
 
143
static int b_rrot (lua_State *L) {
 
144
  return b_rot(L, -luaL_checkint(L, 2));
 
145
}
 
146
 
 
147
 
 
148
/*
 
149
** get field and width arguments for field-manipulation functions,
 
150
** checking whether they are valid.
 
151
** ('luaL_error' called without 'return' to avoid later warnings about
 
152
** 'width' being used uninitialized.)
 
153
*/
 
154
static int fieldargs (lua_State *L, int farg, int *width) {
 
155
  int f = luaL_checkint(L, farg);
 
156
  int w = luaL_optint(L, farg + 1, 1);
 
157
  luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
 
158
  luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
 
159
  if (f + w > LUA_NBITS)
 
160
    luaL_error(L, "trying to access non-existent bits");
 
161
  *width = w;
 
162
  return f;
 
163
}
 
164
 
 
165
 
 
166
static int b_extract (lua_State *L) {
 
167
  int w;
 
168
  b_uint r = luaL_checkunsigned(L, 1);
 
169
  int f = fieldargs(L, 2, &w);
 
170
  r = (r >> f) & mask(w);
 
171
  lua_pushunsigned(L, r);
 
172
  return 1;
 
173
}
 
174
 
 
175
 
 
176
static int b_replace (lua_State *L) {
 
177
  int w;
 
178
  b_uint r = luaL_checkunsigned(L, 1);
 
179
  b_uint v = luaL_checkunsigned(L, 2);
 
180
  int f = fieldargs(L, 3, &w);
 
181
  int m = mask(w);
 
182
  v &= m;  /* erase bits outside given width */
 
183
  r = (r & ~(m << f)) | (v << f);
 
184
  lua_pushunsigned(L, r);
 
185
  return 1;
 
186
}
 
187
 
 
188
 
 
189
static const luaL_Reg bitlib[] = {
 
190
  {"arshift", b_arshift},
 
191
  {"band", b_and},
 
192
  {"bnot", b_not},
 
193
  {"bor", b_or},
 
194
  {"bxor", b_xor},
 
195
  {"btest", b_test},
 
196
  {"extract", b_extract},
 
197
  {"lrotate", b_lrot},
 
198
  {"lshift", b_lshift},
 
199
  {"replace", b_replace},
 
200
  {"rrotate", b_rrot},
 
201
  {"rshift", b_rshift},
 
202
  {NULL, NULL}
 
203
};
 
204
 
 
205
 
 
206
 
 
207
LUAMOD_API int luaopen_bit32 (lua_State *L) {
 
208
  luaL_newlib(L, bitlib);
 
209
  return 1;
 
210
}
 
211