OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/contexts.h" | 9 #include "src/contexts.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 Handle<AccessorInfo> Accessors::StringLengthInfo( | 305 Handle<AccessorInfo> Accessors::StringLengthInfo( |
306 Isolate* isolate, PropertyAttributes attributes) { | 306 Isolate* isolate, PropertyAttributes attributes) { |
307 return MakeAccessor(isolate, | 307 return MakeAccessor(isolate, |
308 isolate->factory()->length_string(), | 308 isolate->factory()->length_string(), |
309 &StringLengthGetter, | 309 &StringLengthGetter, |
310 &StringLengthSetter, | 310 &StringLengthSetter, |
311 attributes); | 311 attributes); |
312 } | 312 } |
313 | 313 |
314 | 314 |
315 template <typename Char> | |
316 inline int CountRequiredEscapes(Handle<String> source) { | |
317 DisallowHeapAllocation no_gc; | |
318 int escapes = 0; | |
319 Vector<const Char> src = source->GetCharVector<Char>(); | |
320 for (int i = 0; i < src.length(); i++) { | |
321 if (src[i] == '/' && (i == 0 || src[i - 1] != '\\')) escapes++; | |
322 } | |
323 return escapes; | |
324 } | |
325 | |
326 | |
327 template <typename Char, typename StringType> | |
328 inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source, | |
329 Handle<StringType> result) { | |
330 DisallowHeapAllocation no_gc; | |
331 Vector<const Char> src = source->GetCharVector<Char>(); | |
332 Vector<Char> dst(result->GetChars(), result->length()); | |
333 int s = 0; | |
334 int d = 0; | |
335 while (s < src.length()) { | |
336 if (src[s] == '/' && (s == 0 || src[s - 1] != '\\')) dst[d++] = '\\'; | |
337 dst[d++] = src[s++]; | |
338 } | |
339 DCHECK_EQ(result->length(), d); | |
340 return result; | |
341 } | |
342 | |
343 | |
344 MaybeHandle<String> EscapeRegExpSource(Isolate* isolate, | |
345 Handle<String> source) { | |
346 String::Flatten(source); | |
347 if (source->length() == 0) return isolate->factory()->query_colon_string(); | |
348 bool one_byte = source->IsOneByteRepresentationUnderneath(); | |
349 int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source) | |
350 : CountRequiredEscapes<uc16>(source); | |
351 if (escapes == 0) return source; | |
352 int length = source->length() + escapes; | |
353 if (one_byte) { | |
354 Handle<SeqOneByteString> result; | |
355 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, | |
356 isolate->factory()->NewRawOneByteString(length), | |
357 String); | |
358 return WriteEscapedRegExpSource<uint8_t>(source, result); | |
359 } else { | |
360 Handle<SeqTwoByteString> result; | |
361 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, | |
362 isolate->factory()->NewRawTwoByteString(length), | |
363 String); | |
364 return WriteEscapedRegExpSource<uc16>(source, result); | |
365 } | |
366 } | |
367 | |
368 | |
369 // Implements ECMA262 ES6 draft 21.2.5.9 | |
370 void Accessors::RegExpSourceGetter( | |
371 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
372 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
373 HandleScope scope(isolate); | |
374 | |
375 Handle<Object> holder = | |
376 Utils::OpenHandle(*v8::Local<v8::Value>(info.Holder())); | |
377 Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(holder); | |
378 Handle<String> result; | |
379 if (regexp->TypeTag() == JSRegExp::NOT_COMPILED) { | |
380 result = isolate->factory()->empty_string(); | |
381 } else { | |
382 Handle<String> pattern(regexp->Pattern(), isolate); | |
383 MaybeHandle<String> maybe = EscapeRegExpSource(isolate, pattern); | |
384 if (!maybe.ToHandle(&result)) { | |
385 isolate->OptionalRescheduleException(false); | |
386 return; | |
387 } | |
388 } | |
389 info.GetReturnValue().Set(Utils::ToLocal(result)); | |
390 } | |
391 | |
392 | |
393 void Accessors::RegExpSourceSetter(v8::Local<v8::Name> name, | |
394 v8::Local<v8::Value> value, | |
395 const v8::PropertyCallbackInfo<void>& info) { | |
396 UNREACHABLE(); | |
397 } | |
398 | |
399 | |
400 Handle<AccessorInfo> Accessors::RegExpSourceInfo( | |
401 Isolate* isolate, PropertyAttributes attributes) { | |
402 return MakeAccessor(isolate, isolate->factory()->source_string(), | |
403 &RegExpSourceGetter, &RegExpSourceSetter, attributes); | |
404 } | |
405 | |
406 | |
407 // | 315 // |
408 // Accessors::ScriptColumnOffset | 316 // Accessors::ScriptColumnOffset |
409 // | 317 // |
410 | 318 |
411 | 319 |
412 void Accessors::ScriptColumnOffsetGetter( | 320 void Accessors::ScriptColumnOffsetGetter( |
413 v8::Local<v8::Name> name, | 321 v8::Local<v8::Name> name, |
414 const v8::PropertyCallbackInfo<v8::Value>& info) { | 322 const v8::PropertyCallbackInfo<v8::Value>& info) { |
415 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 323 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
416 DisallowHeapAllocation no_allocation; | 324 DisallowHeapAllocation no_allocation; |
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 info->set_data(Smi::FromInt(index)); | 1476 info->set_data(Smi::FromInt(index)); |
1569 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); | 1477 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); |
1570 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); | 1478 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); |
1571 info->set_getter(*getter); | 1479 info->set_getter(*getter); |
1572 if (!(attributes & ReadOnly)) info->set_setter(*setter); | 1480 if (!(attributes & ReadOnly)) info->set_setter(*setter); |
1573 return info; | 1481 return info; |
1574 } | 1482 } |
1575 | 1483 |
1576 | 1484 |
1577 } } // namespace v8::internal | 1485 } } // namespace v8::internal |
OLD | NEW |