Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/objects.cc

Issue 1448933002: Introduce a BuiltinsConstructStub that sets up new.target and does a [[call]] per ES6 9.3.2 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-body-descriptors-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 15388 matching lines...) Expand 10 before | Expand all | Expand 10 after
15399 } 15399 }
15400 15400
15401 private: 15401 private:
15402 Handle<String> source_; 15402 Handle<String> source_;
15403 Handle<SharedFunctionInfo> shared_; 15403 Handle<SharedFunctionInfo> shared_;
15404 LanguageMode language_mode_; 15404 LanguageMode language_mode_;
15405 int scope_position_; 15405 int scope_position_;
15406 }; 15406 };
15407 15407
15408 15408
15409 // static
15410 MaybeHandle<JSRegExp> JSRegExp::New(Handle<String> pattern,
15411 Handle<String> flags) {
15412 Isolate* isolate = pattern->GetIsolate();
15413 Handle<JSFunction> constructor = isolate->regexp_function();
15414 Handle<JSRegExp> regexp =
15415 Handle<JSRegExp>::cast(isolate->factory()->NewJSObject(constructor));
15416
15417 return JSRegExp::Initialize(regexp, pattern, flags);
15418 }
15419
15420
15421 static JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags,
15422 bool* success) {
15423 uint32_t value = JSRegExp::NONE;
15424 int length = flags->length();
15425 // A longer flags string cannot be valid.
15426 if (length > 5) return JSRegExp::Flags(0);
15427 for (int i = 0; i < length; i++) {
15428 uint32_t flag = JSRegExp::NONE;
15429 switch (flags->Get(i)) {
15430 case 'g':
15431 flag = JSRegExp::GLOBAL;
15432 break;
15433 case 'i':
15434 flag = JSRegExp::IGNORE_CASE;
15435 break;
15436 case 'm':
15437 flag = JSRegExp::MULTILINE;
15438 break;
15439 case 'u':
15440 if (!FLAG_harmony_unicode_regexps) return JSRegExp::Flags(0);
15441 flag = JSRegExp::UNICODE_ESCAPES;
15442 break;
15443 case 'y':
15444 if (!FLAG_harmony_regexps) return JSRegExp::Flags(0);
15445 flag = JSRegExp::STICKY;
15446 break;
15447 default:
15448 return JSRegExp::Flags(0);
15449 }
15450 // Duplicate flag.
15451 if (value & flag) return JSRegExp::Flags(0);
15452 value |= flag;
15453 }
15454 *success = true;
15455 return JSRegExp::Flags(value);
15456 }
15457
15458
15459 template <typename Char>
15460 inline int CountRequiredEscapes(Handle<String> source) {
15461 DisallowHeapAllocation no_gc;
15462 int escapes = 0;
15463 Vector<const Char> src = source->GetCharVector<Char>();
15464 for (int i = 0; i < src.length(); i++) {
15465 if (src[i] == '/' && (i == 0 || src[i - 1] != '\\')) escapes++;
15466 }
15467 return escapes;
15468 }
15469
15470
15471 template <typename Char, typename StringType>
15472 inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
15473 Handle<StringType> result) {
15474 DisallowHeapAllocation no_gc;
15475 Vector<const Char> src = source->GetCharVector<Char>();
15476 Vector<Char> dst(result->GetChars(), result->length());
15477 int s = 0;
15478 int d = 0;
15479 while (s < src.length()) {
15480 if (src[s] == '/' && (s == 0 || src[s - 1] != '\\')) dst[d++] = '\\';
15481 dst[d++] = src[s++];
15482 }
15483 DCHECK_EQ(result->length(), d);
15484 return result;
15485 }
15486
15487
15488 MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
15489 Handle<String> source) {
15490 String::Flatten(source);
15491 if (source->length() == 0) return isolate->factory()->query_colon_string();
15492 bool one_byte = source->IsOneByteRepresentationUnderneath();
15493 int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
15494 : CountRequiredEscapes<uc16>(source);
15495 if (escapes == 0) return source;
15496 int length = source->length() + escapes;
15497 if (one_byte) {
15498 Handle<SeqOneByteString> result;
15499 ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
15500 isolate->factory()->NewRawOneByteString(length),
15501 String);
15502 return WriteEscapedRegExpSource<uint8_t>(source, result);
15503 } else {
15504 Handle<SeqTwoByteString> result;
15505 ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
15506 isolate->factory()->NewRawTwoByteString(length),
15507 String);
15508 return WriteEscapedRegExpSource<uc16>(source, result);
15509 }
15510 }
15511
15512
15513 // static
15514 MaybeHandle<JSRegExp> JSRegExp::Initialize(Handle<JSRegExp> regexp,
15515 Handle<String> source,
15516 Handle<String> flags_string) {
15517 Isolate* isolate = regexp->GetIsolate();
15518 Factory* factory = isolate->factory();
15519 // If source is the empty string we set it to "(?:)" instead as
15520 // suggested by ECMA-262, 5th, section 15.10.4.1.
15521 if (source->length() == 0) source = factory->query_colon_string();
15522
15523 bool success = false;
15524 JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success);
15525 if (!success) {
15526 THROW_NEW_ERROR(
15527 isolate,
15528 NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string),
15529 JSRegExp);
15530 }
15531
15532 Handle<String> escaped_source;
15533 ASSIGN_RETURN_ON_EXCEPTION(isolate, escaped_source,
15534 EscapeRegExpSource(isolate, source), JSRegExp);
15535
15536 regexp->set_source(*escaped_source);
15537 regexp->set_flags(Smi::FromInt(flags.value()));
15538
15539 Map* map = regexp->map();
15540 Object* constructor = map->GetConstructor();
15541 if (constructor->IsJSFunction() &&
15542 JSFunction::cast(constructor)->initial_map() == map) {
15543 // If we still have the original map, set in-object properties directly.
15544 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
15545 Smi::FromInt(0), SKIP_WRITE_BARRIER);
15546 } else {
15547 // Map has changed, so use generic, but slower, method.
15548 PropertyAttributes writable =
15549 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
15550 JSObject::SetOwnPropertyIgnoreAttributes(
15551 regexp, factory->last_index_string(),
15552 Handle<Smi>(Smi::FromInt(0), isolate), writable)
15553 .Check();
15554 }
15555
15556 RETURN_ON_EXCEPTION(isolate, RegExpImpl::Compile(regexp, source, flags),
15557 JSRegExp);
15558
15559 return regexp;
15560 }
15561
15562
15409 // RegExpKey carries the source and flags of a regular expression as key. 15563 // RegExpKey carries the source and flags of a regular expression as key.
15410 class RegExpKey : public HashTableKey { 15564 class RegExpKey : public HashTableKey {
15411 public: 15565 public:
15412 RegExpKey(Handle<String> string, JSRegExp::Flags flags) 15566 RegExpKey(Handle<String> string, JSRegExp::Flags flags)
15413 : string_(string), 15567 : string_(string),
15414 flags_(Smi::FromInt(flags.value())) { } 15568 flags_(Smi::FromInt(flags.value())) { }
15415 15569
15416 // Rather than storing the key in the hash table, a pointer to the 15570 // Rather than storing the key in the hash table, a pointer to the
15417 // stored value is stored where the key should be. IsMatch then 15571 // stored value is stored where the key should be. IsMatch then
15418 // compares the search key to the found object, rather than comparing 15572 // compares the search key to the found object, rather than comparing
(...skipping 2704 matching lines...) Expand 10 before | Expand all | Expand 10 after
18123 if (cell->value() != *new_value) { 18277 if (cell->value() != *new_value) {
18124 cell->set_value(*new_value); 18278 cell->set_value(*new_value);
18125 Isolate* isolate = cell->GetIsolate(); 18279 Isolate* isolate = cell->GetIsolate();
18126 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18280 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18127 isolate, DependentCode::kPropertyCellChangedGroup); 18281 isolate, DependentCode::kPropertyCellChangedGroup);
18128 } 18282 }
18129 } 18283 }
18130 18284
18131 } // namespace internal 18285 } // namespace internal
18132 } // namespace v8 18286 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-body-descriptors-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698