~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/conversions.cc

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2011 the V8 project authors. All rights reserved.
 
2
// Redistribution and use in source and binary forms, with or without
 
3
// modification, are permitted provided that the following conditions are
 
4
// met:
 
5
//
 
6
//     * Redistributions of source code must retain the above copyright
 
7
//       notice, this list of conditions and the following disclaimer.
 
8
//     * Redistributions in binary form must reproduce the above
 
9
//       copyright notice, this list of conditions and the following
 
10
//       disclaimer in the documentation and/or other materials provided
 
11
//       with the distribution.
 
12
//     * Neither the name of Google Inc. nor the names of its
 
13
//       contributors may be used to endorse or promote products derived
 
14
//       from this software without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
#include <stdarg.h>
 
29
#include <math.h>
 
30
#include <limits.h>
 
31
 
 
32
#include "conversions-inl.h"
 
33
#include "dtoa.h"
 
34
#include "strtod.h"
 
35
#include "utils.h"
 
36
 
 
37
namespace v8 {
 
38
namespace internal {
 
39
 
 
40
 
 
41
double StringToDouble(UnicodeCache* unicode_cache,
 
42
                      const char* str, int flags, double empty_string_val) {
 
43
  const char* end = str + StrLength(str);
 
44
  return InternalStringToDouble(unicode_cache, str, end, flags,
 
45
                                empty_string_val);
 
46
}
 
47
 
 
48
 
 
49
double StringToDouble(UnicodeCache* unicode_cache,
 
50
                      Vector<const char> str,
 
51
                      int flags,
 
52
                      double empty_string_val) {
 
53
  const char* end = str.start() + str.length();
 
54
  return InternalStringToDouble(unicode_cache, str.start(), end, flags,
 
55
                                empty_string_val);
 
56
}
 
57
 
 
58
double StringToDouble(UnicodeCache* unicode_cache,
 
59
                      Vector<const uc16> str,
 
60
                      int flags,
 
61
                      double empty_string_val) {
 
62
  const uc16* end = str.start() + str.length();
 
63
  return InternalStringToDouble(unicode_cache, str.start(), end, flags,
 
64
                                empty_string_val);
 
65
}
 
66
 
 
67
 
 
68
const char* DoubleToCString(double v, Vector<char> buffer) {
 
69
  switch (fpclassify(v)) {
 
70
    case FP_NAN: return "NaN";
 
71
    case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
 
72
    case FP_ZERO: return "0";
 
73
    default: {
 
74
      SimpleStringBuilder builder(buffer.start(), buffer.length());
 
75
      int decimal_point;
 
76
      int sign;
 
77
      const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
 
78
      char decimal_rep[kV8DtoaBufferCapacity];
 
79
      int length;
 
80
 
 
81
      DoubleToAscii(v, DTOA_SHORTEST, 0,
 
82
                    Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
 
83
                    &sign, &length, &decimal_point);
 
84
 
 
85
      if (sign) builder.AddCharacter('-');
 
86
 
 
87
      if (length <= decimal_point && decimal_point <= 21) {
 
88
        // ECMA-262 section 9.8.1 step 6.
 
89
        builder.AddString(decimal_rep);
 
90
        builder.AddPadding('0', decimal_point - length);
 
91
 
 
92
      } else if (0 < decimal_point && decimal_point <= 21) {
 
93
        // ECMA-262 section 9.8.1 step 7.
 
94
        builder.AddSubstring(decimal_rep, decimal_point);
 
95
        builder.AddCharacter('.');
 
96
        builder.AddString(decimal_rep + decimal_point);
 
97
 
 
98
      } else if (decimal_point <= 0 && decimal_point > -6) {
 
99
        // ECMA-262 section 9.8.1 step 8.
 
100
        builder.AddString("0.");
 
101
        builder.AddPadding('0', -decimal_point);
 
102
        builder.AddString(decimal_rep);
 
103
 
 
104
      } else {
 
105
        // ECMA-262 section 9.8.1 step 9 and 10 combined.
 
106
        builder.AddCharacter(decimal_rep[0]);
 
107
        if (length != 1) {
 
108
          builder.AddCharacter('.');
 
109
          builder.AddString(decimal_rep + 1);
 
110
        }
 
111
        builder.AddCharacter('e');
 
112
        builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
 
113
        int exponent = decimal_point - 1;
 
114
        if (exponent < 0) exponent = -exponent;
 
115
        builder.AddDecimalInteger(exponent);
 
116
      }
 
117
    return builder.Finalize();
 
118
    }
 
119
  }
 
120
}
 
121
 
 
122
 
 
123
const char* IntToCString(int n, Vector<char> buffer) {
 
124
  bool negative = false;
 
125
  if (n < 0) {
 
126
    // We must not negate the most negative int.
 
127
    if (n == kMinInt) return DoubleToCString(n, buffer);
 
128
    negative = true;
 
129
    n = -n;
 
130
  }
 
131
  // Build the string backwards from the least significant digit.
 
132
  int i = buffer.length();
 
133
  buffer[--i] = '\0';
 
134
  do {
 
135
    buffer[--i] = '0' + (n % 10);
 
136
    n /= 10;
 
137
  } while (n);
 
138
  if (negative) buffer[--i] = '-';
 
139
  return buffer.start() + i;
 
140
}
 
141
 
 
142
 
 
143
char* DoubleToFixedCString(double value, int f) {
 
144
  const int kMaxDigitsBeforePoint = 21;
 
145
  const double kFirstNonFixed = 1e21;
 
146
  const int kMaxDigitsAfterPoint = 20;
 
147
  ASSERT(f >= 0);
 
148
  ASSERT(f <= kMaxDigitsAfterPoint);
 
149
 
 
150
  bool negative = false;
 
151
  double abs_value = value;
 
152
  if (value < 0) {
 
153
    abs_value = -value;
 
154
    negative = true;
 
155
  }
 
156
 
 
157
  // If abs_value has more than kMaxDigitsBeforePoint digits before the point
 
158
  // use the non-fixed conversion routine.
 
159
  if (abs_value >= kFirstNonFixed) {
 
160
    char arr[100];
 
161
    Vector<char> buffer(arr, ARRAY_SIZE(arr));
 
162
    return StrDup(DoubleToCString(value, buffer));
 
163
  }
 
164
 
 
165
  // Find a sufficiently precise decimal representation of n.
 
166
  int decimal_point;
 
167
  int sign;
 
168
  // Add space for the '\0' byte.
 
169
  const int kDecimalRepCapacity =
 
170
      kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1;
 
171
  char decimal_rep[kDecimalRepCapacity];
 
172
  int decimal_rep_length;
 
173
  DoubleToAscii(value, DTOA_FIXED, f,
 
174
                Vector<char>(decimal_rep, kDecimalRepCapacity),
 
175
                &sign, &decimal_rep_length, &decimal_point);
 
176
 
 
177
  // Create a representation that is padded with zeros if needed.
 
178
  int zero_prefix_length = 0;
 
179
  int zero_postfix_length = 0;
 
180
 
 
181
  if (decimal_point <= 0) {
 
182
    zero_prefix_length = -decimal_point + 1;
 
183
    decimal_point = 1;
 
184
  }
 
185
 
 
186
  if (zero_prefix_length + decimal_rep_length < decimal_point + f) {
 
187
    zero_postfix_length = decimal_point + f - decimal_rep_length -
 
188
                          zero_prefix_length;
 
189
  }
 
190
 
 
191
  unsigned rep_length =
 
192
      zero_prefix_length + decimal_rep_length + zero_postfix_length;
 
193
  SimpleStringBuilder rep_builder(rep_length + 1);
 
194
  rep_builder.AddPadding('0', zero_prefix_length);
 
195
  rep_builder.AddString(decimal_rep);
 
196
  rep_builder.AddPadding('0', zero_postfix_length);
 
197
  char* rep = rep_builder.Finalize();
 
198
 
 
199
  // Create the result string by appending a minus and putting in a
 
200
  // decimal point if needed.
 
201
  unsigned result_size = decimal_point + f + 2;
 
202
  SimpleStringBuilder builder(result_size + 1);
 
203
  if (negative) builder.AddCharacter('-');
 
204
  builder.AddSubstring(rep, decimal_point);
 
205
  if (f > 0) {
 
206
    builder.AddCharacter('.');
 
207
    builder.AddSubstring(rep + decimal_point, f);
 
208
  }
 
209
  DeleteArray(rep);
 
210
  return builder.Finalize();
 
211
}
 
212
 
 
213
 
 
214
static char* CreateExponentialRepresentation(char* decimal_rep,
 
215
                                             int exponent,
 
216
                                             bool negative,
 
217
                                             int significant_digits) {
 
218
  bool negative_exponent = false;
 
219
  if (exponent < 0) {
 
220
    negative_exponent = true;
 
221
    exponent = -exponent;
 
222
  }
 
223
 
 
224
  // Leave room in the result for appending a minus, for a period, the
 
225
  // letter 'e', a minus or a plus depending on the exponent, and a
 
226
  // three digit exponent.
 
227
  unsigned result_size = significant_digits + 7;
 
228
  SimpleStringBuilder builder(result_size + 1);
 
229
 
 
230
  if (negative) builder.AddCharacter('-');
 
231
  builder.AddCharacter(decimal_rep[0]);
 
232
  if (significant_digits != 1) {
 
233
    builder.AddCharacter('.');
 
234
    builder.AddString(decimal_rep + 1);
 
235
    int rep_length = StrLength(decimal_rep);
 
236
    builder.AddPadding('0', significant_digits - rep_length);
 
237
  }
 
238
 
 
239
  builder.AddCharacter('e');
 
240
  builder.AddCharacter(negative_exponent ? '-' : '+');
 
241
  builder.AddDecimalInteger(exponent);
 
242
  return builder.Finalize();
 
243
}
 
244
 
 
245
 
 
246
 
 
247
char* DoubleToExponentialCString(double value, int f) {
 
248
  const int kMaxDigitsAfterPoint = 20;
 
249
  // f might be -1 to signal that f was undefined in JavaScript.
 
250
  ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint);
 
251
 
 
252
  bool negative = false;
 
253
  if (value < 0) {
 
254
    value = -value;
 
255
    negative = true;
 
256
  }
 
257
 
 
258
  // Find a sufficiently precise decimal representation of n.
 
259
  int decimal_point;
 
260
  int sign;
 
261
  // f corresponds to the digits after the point. There is always one digit
 
262
  // before the point. The number of requested_digits equals hence f + 1.
 
263
  // And we have to add one character for the null-terminator.
 
264
  const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1;
 
265
  // Make sure that the buffer is big enough, even if we fall back to the
 
266
  // shortest representation (which happens when f equals -1).
 
267
  ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1);
 
268
  char decimal_rep[kV8DtoaBufferCapacity];
 
269
  int decimal_rep_length;
 
270
 
 
271
  if (f == -1) {
 
272
    DoubleToAscii(value, DTOA_SHORTEST, 0,
 
273
                  Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
 
274
                  &sign, &decimal_rep_length, &decimal_point);
 
275
    f = decimal_rep_length - 1;
 
276
  } else {
 
277
    DoubleToAscii(value, DTOA_PRECISION, f + 1,
 
278
                  Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
 
279
                  &sign, &decimal_rep_length, &decimal_point);
 
280
  }
 
281
  ASSERT(decimal_rep_length > 0);
 
282
  ASSERT(decimal_rep_length <= f + 1);
 
283
 
 
284
  int exponent = decimal_point - 1;
 
285
  char* result =
 
286
      CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1);
 
287
 
 
288
  return result;
 
289
}
 
290
 
 
291
 
 
292
char* DoubleToPrecisionCString(double value, int p) {
 
293
  const int kMinimalDigits = 1;
 
294
  const int kMaximalDigits = 21;
 
295
  ASSERT(p >= kMinimalDigits && p <= kMaximalDigits);
 
296
  USE(kMinimalDigits);
 
297
 
 
298
  bool negative = false;
 
299
  if (value < 0) {
 
300
    value = -value;
 
301
    negative = true;
 
302
  }
 
303
 
 
304
  // Find a sufficiently precise decimal representation of n.
 
305
  int decimal_point;
 
306
  int sign;
 
307
  // Add one for the terminating null character.
 
308
  const int kV8DtoaBufferCapacity = kMaximalDigits + 1;
 
309
  char decimal_rep[kV8DtoaBufferCapacity];
 
310
  int decimal_rep_length;
 
311
 
 
312
  DoubleToAscii(value, DTOA_PRECISION, p,
 
313
                Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
 
314
                &sign, &decimal_rep_length, &decimal_point);
 
315
  ASSERT(decimal_rep_length <= p);
 
316
 
 
317
  int exponent = decimal_point - 1;
 
318
 
 
319
  char* result = NULL;
 
320
 
 
321
  if (exponent < -6 || exponent >= p) {
 
322
    result =
 
323
        CreateExponentialRepresentation(decimal_rep, exponent, negative, p);
 
324
  } else {
 
325
    // Use fixed notation.
 
326
    //
 
327
    // Leave room in the result for appending a minus, a period and in
 
328
    // the case where decimal_point is not positive for a zero in
 
329
    // front of the period.
 
330
    unsigned result_size = (decimal_point <= 0)
 
331
        ? -decimal_point + p + 3
 
332
        : p + 2;
 
333
    SimpleStringBuilder builder(result_size + 1);
 
334
    if (negative) builder.AddCharacter('-');
 
335
    if (decimal_point <= 0) {
 
336
      builder.AddString("0.");
 
337
      builder.AddPadding('0', -decimal_point);
 
338
      builder.AddString(decimal_rep);
 
339
      builder.AddPadding('0', p - decimal_rep_length);
 
340
    } else {
 
341
      const int m = Min(decimal_rep_length, decimal_point);
 
342
      builder.AddSubstring(decimal_rep, m);
 
343
      builder.AddPadding('0', decimal_point - decimal_rep_length);
 
344
      if (decimal_point < p) {
 
345
        builder.AddCharacter('.');
 
346
        const int extra = negative ? 2 : 1;
 
347
        if (decimal_rep_length > decimal_point) {
 
348
          const int len = StrLength(decimal_rep + decimal_point);
 
349
          const int n = Min(len, p - (builder.position() - extra));
 
350
          builder.AddSubstring(decimal_rep + decimal_point, n);
 
351
        }
 
352
        builder.AddPadding('0', extra + (p - builder.position()));
 
353
      }
 
354
    }
 
355
    result = builder.Finalize();
 
356
  }
 
357
 
 
358
  return result;
 
359
}
 
360
 
 
361
 
 
362
char* DoubleToRadixCString(double value, int radix) {
 
363
  ASSERT(radix >= 2 && radix <= 36);
 
364
 
 
365
  // Character array used for conversion.
 
366
  static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 
367
 
 
368
  // Buffer for the integer part of the result. 1024 chars is enough
 
369
  // for max integer value in radix 2.  We need room for a sign too.
 
370
  static const int kBufferSize = 1100;
 
371
  char integer_buffer[kBufferSize];
 
372
  integer_buffer[kBufferSize - 1] = '\0';
 
373
 
 
374
  // Buffer for the decimal part of the result.  We only generate up
 
375
  // to kBufferSize - 1 chars for the decimal part.
 
376
  char decimal_buffer[kBufferSize];
 
377
  decimal_buffer[kBufferSize - 1] = '\0';
 
378
 
 
379
  // Make sure the value is positive.
 
380
  bool is_negative = value < 0.0;
 
381
  if (is_negative) value = -value;
 
382
 
 
383
  // Get the integer part and the decimal part.
 
384
  double integer_part = floor(value);
 
385
  double decimal_part = value - integer_part;
 
386
 
 
387
  // Convert the integer part starting from the back.  Always generate
 
388
  // at least one digit.
 
389
  int integer_pos = kBufferSize - 2;
 
390
  do {
 
391
    integer_buffer[integer_pos--] =
 
392
        chars[static_cast<int>(fmod(integer_part, radix))];
 
393
    integer_part /= radix;
 
394
  } while (integer_part >= 1.0);
 
395
  // Sanity check.
 
396
  ASSERT(integer_pos > 0);
 
397
  // Add sign if needed.
 
398
  if (is_negative) integer_buffer[integer_pos--] = '-';
 
399
 
 
400
  // Convert the decimal part.  Repeatedly multiply by the radix to
 
401
  // generate the next char.  Never generate more than kBufferSize - 1
 
402
  // chars.
 
403
  //
 
404
  // TODO(1093998): We will often generate a full decimal_buffer of
 
405
  // chars because hitting zero will often not happen.  The right
 
406
  // solution would be to continue until the string representation can
 
407
  // be read back and yield the original value.  To implement this
 
408
  // efficiently, we probably have to modify dtoa.
 
409
  int decimal_pos = 0;
 
410
  while ((decimal_part > 0.0) && (decimal_pos < kBufferSize - 1)) {
 
411
    decimal_part *= radix;
 
412
    decimal_buffer[decimal_pos++] =
 
413
        chars[static_cast<int>(floor(decimal_part))];
 
414
    decimal_part -= floor(decimal_part);
 
415
  }
 
416
  decimal_buffer[decimal_pos] = '\0';
 
417
 
 
418
  // Compute the result size.
 
419
  int integer_part_size = kBufferSize - 2 - integer_pos;
 
420
  // Make room for zero termination.
 
421
  unsigned result_size = integer_part_size + decimal_pos;
 
422
  // If the number has a decimal part, leave room for the period.
 
423
  if (decimal_pos > 0) result_size++;
 
424
  // Allocate result and fill in the parts.
 
425
  SimpleStringBuilder builder(result_size + 1);
 
426
  builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size);
 
427
  if (decimal_pos > 0) builder.AddCharacter('.');
 
428
  builder.AddSubstring(decimal_buffer, decimal_pos);
 
429
  return builder.Finalize();
 
430
}
 
431
 
 
432
} }  // namespace v8::internal