v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
v8utils.cc
Go to the documentation of this file.
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 
30 #include "v8.h"
31 
32 #include "platform.h"
33 
34 #include "sys/stat.h"
35 
36 namespace v8 {
37 namespace internal {
38 
39 
40 void PrintF(const char* format, ...) {
41  va_list arguments;
42  va_start(arguments, format);
43  OS::VPrint(format, arguments);
44  va_end(arguments);
45 }
46 
47 
48 void PrintF(FILE* out, const char* format, ...) {
49  va_list arguments;
50  va_start(arguments, format);
51  OS::VFPrint(out, format, arguments);
52  va_end(arguments);
53 }
54 
55 
56 void Flush(FILE* out) {
57  fflush(out);
58 }
59 
60 
61 char* ReadLine(const char* prompt) {
62  char* result = NULL;
63  char line_buf[256];
64  int offset = 0;
65  bool keep_going = true;
66  fprintf(stdout, "%s", prompt);
67  fflush(stdout);
68  while (keep_going) {
69  if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
70  // fgets got an error. Just give up.
71  if (result != NULL) {
72  DeleteArray(result);
73  }
74  return NULL;
75  }
76  int len = StrLength(line_buf);
77  if (len > 1 &&
78  line_buf[len - 2] == '\\' &&
79  line_buf[len - 1] == '\n') {
80  // When we read a line that ends with a "\" we remove the escape and
81  // append the remainder.
82  line_buf[len - 2] = '\n';
83  line_buf[len - 1] = 0;
84  len -= 1;
85  } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
86  // Since we read a new line we are done reading the line. This
87  // will exit the loop after copying this buffer into the result.
88  keep_going = false;
89  }
90  if (result == NULL) {
91  // Allocate the initial result and make room for the terminating '\0'
92  result = NewArray<char>(len + 1);
93  } else {
94  // Allocate a new result with enough room for the new addition.
95  int new_len = offset + len + 1;
96  char* new_result = NewArray<char>(new_len);
97  // Copy the existing input into the new array and set the new
98  // array as the result.
99  memcpy(new_result, result, offset * kCharSize);
100  DeleteArray(result);
101  result = new_result;
102  }
103  // Copy the newly read line into the result.
104  memcpy(result + offset, line_buf, len * kCharSize);
105  offset += len;
106  }
107  ASSERT(result != NULL);
108  result[offset] = '\0';
109  return result;
110 }
111 
112 
113 char* ReadCharsFromFile(FILE* file,
114  int* size,
115  int extra_space,
116  bool verbose,
117  const char* filename) {
118  if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
119  if (verbose) {
120  OS::PrintError("Cannot read from file %s.\n", filename);
121  }
122  return NULL;
123  }
124 
125  // Get the size of the file and rewind it.
126  *size = ftell(file);
127  rewind(file);
128 
129  char* result = NewArray<char>(*size + extra_space);
130  for (int i = 0; i < *size && feof(file) == 0;) {
131  int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
132  if (read != (*size - i) && ferror(file) != 0) {
133  fclose(file);
134  DeleteArray(result);
135  return NULL;
136  }
137  i += read;
138  }
139  return result;
140 }
141 
142 
143 char* ReadCharsFromFile(const char* filename,
144  int* size,
145  int extra_space,
146  bool verbose) {
147  FILE* file = OS::FOpen(filename, "rb");
148  char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
149  if (file != NULL) fclose(file);
150  return result;
151 }
152 
153 
154 byte* ReadBytes(const char* filename, int* size, bool verbose) {
155  char* chars = ReadCharsFromFile(filename, size, 0, verbose);
156  return reinterpret_cast<byte*>(chars);
157 }
158 
159 
160 static Vector<const char> SetVectorContents(char* chars,
161  int size,
162  bool* exists) {
163  if (!chars) {
164  *exists = false;
165  return Vector<const char>::empty();
166  }
167  chars[size] = '\0';
168  *exists = true;
169  return Vector<const char>(chars, size);
170 }
171 
172 
173 Vector<const char> ReadFile(const char* filename,
174  bool* exists,
175  bool verbose) {
176  int size;
177  char* result = ReadCharsFromFile(filename, &size, 1, verbose);
178  return SetVectorContents(result, size, exists);
179 }
180 
181 
183  bool* exists,
184  bool verbose) {
185  int size;
186  char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
187  return SetVectorContents(result, size, exists);
188 }
189 
190 
191 int WriteCharsToFile(const char* str, int size, FILE* f) {
192  int total = 0;
193  while (total < size) {
194  int write = static_cast<int>(fwrite(str, 1, size - total, f));
195  if (write == 0) {
196  return total;
197  }
198  total += write;
199  str += write;
200  }
201  return total;
202 }
203 
204 
205 int AppendChars(const char* filename,
206  const char* str,
207  int size,
208  bool verbose) {
209  FILE* f = OS::FOpen(filename, "ab");
210  if (f == NULL) {
211  if (verbose) {
212  OS::PrintError("Cannot open file %s for writing.\n", filename);
213  }
214  return 0;
215  }
216  int written = WriteCharsToFile(str, size, f);
217  fclose(f);
218  return written;
219 }
220 
221 
222 int WriteChars(const char* filename,
223  const char* str,
224  int size,
225  bool verbose) {
226  FILE* f = OS::FOpen(filename, "wb");
227  if (f == NULL) {
228  if (verbose) {
229  OS::PrintError("Cannot open file %s for writing.\n", filename);
230  }
231  return 0;
232  }
233  int written = WriteCharsToFile(str, size, f);
234  fclose(f);
235  return written;
236 }
237 
238 
239 int WriteBytes(const char* filename,
240  const byte* bytes,
241  int size,
242  bool verbose) {
243  const char* str = reinterpret_cast<const char*>(bytes);
244  return WriteChars(filename, str, size, verbose);
245 }
246 
247 
248 
249 void StringBuilder::AddFormatted(const char* format, ...) {
250  va_list arguments;
251  va_start(arguments, format);
252  AddFormattedList(format, arguments);
253  va_end(arguments);
254 }
255 
256 
257 void StringBuilder::AddFormattedList(const char* format, va_list list) {
259  int n = OS::VSNPrintF(buffer_ + position_, format, list);
260  if (n < 0 || n >= (buffer_.length() - position_)) {
262  } else {
263  position_ += n;
264  }
265 }
266 
267 
269  : filename_(NULL),
270  data_(NULL),
271  length_(0),
272  remove_file_on_cleanup_(false) {
273  Init(filename);
274 }
275 
276 
278  MemoryMappedExternalResource(const char* filename,
279  bool remove_file_on_cleanup)
280  : filename_(NULL),
281  data_(NULL),
282  length_(0),
283  remove_file_on_cleanup_(remove_file_on_cleanup) {
284  Init(filename);
285 }
286 
287 
289  // Release the resources if we had successfully acquired them:
290  if (file_ != NULL) {
291  delete file_;
292  if (remove_file_on_cleanup_) {
293  OS::Remove(filename_);
294  }
295  DeleteArray<char>(filename_);
296  }
297 }
298 
299 
300 void MemoryMappedExternalResource::Init(const char* filename) {
301  file_ = OS::MemoryMappedFile::open(filename);
302  if (file_ != NULL) {
303  filename_ = StrDup(filename);
304  data_ = reinterpret_cast<char*>(file_->memory());
305  length_ = file_->size();
306  }
307 }
308 
309 
310 bool MemoryMappedExternalResource::EnsureIsAscii(bool abort_if_failed) const {
311  bool is_ascii = true;
312 
313  int line_no = 1;
314  const char* start_of_line = data_;
315  const char* end = data_ + length_;
316  for (const char* p = data_; p < end; p++) {
317  char c = *p;
318  if ((c & 0x80) != 0) {
319  // Non-ASCII detected:
320  is_ascii = false;
321 
322  // Report the error and abort if appropriate:
323  if (abort_if_failed) {
324  int char_no = static_cast<int>(p - start_of_line) - 1;
325 
326  ASSERT(filename_ != NULL);
327  PrintF("\n\n\n"
328  "Abort: Non-Ascii character 0x%.2x in file %s line %d char %d",
329  c, filename_, line_no, char_no);
330 
331  // Allow for some context up to kNumberOfLeadingContextChars chars
332  // before the offending non-ASCII char to help the user see where
333  // the offending char is.
334  const int kNumberOfLeadingContextChars = 10;
335  const char* err_context = p - kNumberOfLeadingContextChars;
336  if (err_context < data_) {
337  err_context = data_;
338  }
339  // Compute the length of the error context and print it.
340  int err_context_length = static_cast<int>(p - err_context);
341  if (err_context_length != 0) {
342  PrintF(" after \"%.*s\"", err_context_length, err_context);
343  }
344  PrintF(".\n\n\n");
345  OS::Abort();
346  }
347 
348  break; // Non-ASCII detected. No need to continue scanning.
349  }
350  if (c == '\n') {
351  start_of_line = p;
352  line_no++;
353  }
354  }
355 
356  return is_ascii;
357 }
358 
359 
360 } } // namespace v8::internal
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static int VSNPrintF(Vector< char > str, const char *format, va_list args)
char * ReadCharsFromFile(FILE *file, int *size, int extra_space, bool verbose, const char *filename)
Definition: v8utils.cc:113
#define ASSERT(condition)
Definition: checks.h:270
static void VFPrint(FILE *out, const char *format, va_list args)
byte * ReadBytes(const char *filename, int *size, bool verbose)
Definition: v8utils.cc:154
char * ReadLine(const char *prompt)
Definition: v8utils.cc:61
static MemoryMappedFile * open(const char *name)
uint8_t byte
Definition: globals.h:171
static void Abort()
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
Definition: v8utils.cc:173
static FILE * FOpen(const char *path, const char *mode)
static void VPrint(const char *format, va_list args)
void AddFormatted(const char *format,...)
Definition: v8utils.cc:249
int length() const
Definition: utils.h:383
int WriteCharsToFile(const char *str, int size, FILE *f)
Definition: v8utils.cc:191
int StrLength(const char *string)
Definition: utils.h:234
void AddFormattedList(const char *format, va_list list)
Definition: v8utils.cc:257
int WriteChars(const char *filename, const char *str, int size, bool verbose)
Definition: v8utils.cc:222
int AppendChars(const char *filename, const char *str, int size, bool verbose)
Definition: v8utils.cc:205
static void PrintError(const char *format,...)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
static Vector< T > empty()
Definition: utils.h:441
char * StrDup(const char *str)
Definition: allocation.cc:85
static bool Remove(const char *path)
int WriteBytes(const char *filename, const byte *bytes, int size, bool verbose)
Definition: v8utils.cc:239
void DeleteArray(T *array)
Definition: allocation.h:91
void Flush(FILE *out)
Definition: v8utils.cc:56
const int kCharSize
Definition: globals.h:229
MemoryMappedExternalResource(const char *filename)
Definition: v8utils.cc:268