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

Side by Side Diff: src/runtime.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Modified: svn:mergeinfo
Merged /branches/bleeding_edge/src/runtime.cc:r8062-8597
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 27 matching lines...) Expand all
38 #include "cpu.h" 38 #include "cpu.h"
39 #include "dateparser-inl.h" 39 #include "dateparser-inl.h"
40 #include "debug.h" 40 #include "debug.h"
41 #include "deoptimizer.h" 41 #include "deoptimizer.h"
42 #include "execution.h" 42 #include "execution.h"
43 #include "global-handles.h" 43 #include "global-handles.h"
44 #include "jsregexp.h" 44 #include "jsregexp.h"
45 #include "json-parser.h" 45 #include "json-parser.h"
46 #include "liveedit.h" 46 #include "liveedit.h"
47 #include "liveobjectlist-inl.h" 47 #include "liveobjectlist-inl.h"
48 #include "misc-intrinsics.h"
48 #include "parser.h" 49 #include "parser.h"
49 #include "platform.h" 50 #include "platform.h"
50 #include "runtime-profiler.h" 51 #include "runtime-profiler.h"
51 #include "runtime.h" 52 #include "runtime.h"
52 #include "scopeinfo.h" 53 #include "scopeinfo.h"
53 #include "smart-pointer.h" 54 #include "smart-pointer.h"
54 #include "string-search.h" 55 #include "string-search.h"
55 #include "stub-cache.h" 56 #include "stub-cache.h"
56 #include "v8threads.h" 57 #include "v8threads.h"
57 #include "vm-state-inl.h" 58 #include "vm-state-inl.h"
(...skipping 16 matching lines...) Expand all
74 RUNTIME_ASSERT(args[index]->Is##Type()); \ 75 RUNTIME_ASSERT(args[index]->Is##Type()); \
75 Handle<Type> name = args.at<Type>(index); 76 Handle<Type> name = args.at<Type>(index);
76 77
77 // Cast the given object to a boolean and store it in a variable with 78 // Cast the given object to a boolean and store it in a variable with
78 // the given name. If the object is not a boolean call IllegalOperation 79 // the given name. If the object is not a boolean call IllegalOperation
79 // and return. 80 // and return.
80 #define CONVERT_BOOLEAN_CHECKED(name, obj) \ 81 #define CONVERT_BOOLEAN_CHECKED(name, obj) \
81 RUNTIME_ASSERT(obj->IsBoolean()); \ 82 RUNTIME_ASSERT(obj->IsBoolean()); \
82 bool name = (obj)->IsTrue(); 83 bool name = (obj)->IsTrue();
83 84
84 // Cast the given object to a Smi and store its value in an int variable 85 // Cast the given argument to a Smi and store its value in an int variable
85 // with the given name. If the object is not a Smi call IllegalOperation 86 // with the given name. If the argument is not a Smi call IllegalOperation
86 // and return. 87 // and return.
87 #define CONVERT_SMI_CHECKED(name, obj) \ 88 #define CONVERT_SMI_ARG_CHECKED(name, index) \
88 RUNTIME_ASSERT(obj->IsSmi()); \ 89 RUNTIME_ASSERT(args[index]->IsSmi()); \
89 int name = Smi::cast(obj)->value(); 90 int name = args.smi_at(index);
90 91
91 // Cast the given object to a double and store it in a variable with 92 // Cast the given argument to a double and store it in a variable with
92 // the given name. If the object is not a number (as opposed to 93 // the given name. If the argument is not a number (as opposed to
93 // the number not-a-number) call IllegalOperation and return. 94 // the number not-a-number) call IllegalOperation and return.
94 #define CONVERT_DOUBLE_CHECKED(name, obj) \ 95 #define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
95 RUNTIME_ASSERT(obj->IsNumber()); \ 96 RUNTIME_ASSERT(args[index]->IsNumber()); \
96 double name = (obj)->Number(); 97 double name = args.number_at(index);
97 98
98 // Call the specified converter on the object *comand store the result in 99 // Call the specified converter on the object *comand store the result in
99 // a variable of the specified type with the given name. If the 100 // a variable of the specified type with the given name. If the
100 // object is not a Number call IllegalOperation and return. 101 // object is not a Number call IllegalOperation and return.
101 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ 102 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \
102 RUNTIME_ASSERT(obj->IsNumber()); \ 103 RUNTIME_ASSERT(obj->IsNumber()); \
103 type name = NumberTo##Type(obj); 104 type name = NumberTo##Type(obj);
104 105
105 106
106 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, 107 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 476
476 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralBoilerplate) { 477 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralBoilerplate) {
477 // Takes a FixedArray of elements containing the literal elements of 478 // Takes a FixedArray of elements containing the literal elements of
478 // the array literal and produces JSArray with those elements. 479 // the array literal and produces JSArray with those elements.
479 // Additionally takes the literals array of the surrounding function 480 // Additionally takes the literals array of the surrounding function
480 // which contains the context from which to get the Array function 481 // which contains the context from which to get the Array function
481 // to use for creating the array literal. 482 // to use for creating the array literal.
482 HandleScope scope(isolate); 483 HandleScope scope(isolate);
483 ASSERT(args.length() == 3); 484 ASSERT(args.length() == 3);
484 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 485 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
485 CONVERT_SMI_CHECKED(literals_index, args[1]); 486 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
486 CONVERT_ARG_CHECKED(FixedArray, elements, 2); 487 CONVERT_ARG_CHECKED(FixedArray, elements, 2);
487 488
488 Handle<Object> object = 489 Handle<Object> object =
489 CreateArrayLiteralBoilerplate(isolate, literals, elements); 490 CreateArrayLiteralBoilerplate(isolate, literals, elements);
490 if (object.is_null()) return Failure::Exception(); 491 if (object.is_null()) return Failure::Exception();
491 492
492 // Update the functions literal and return the boilerplate. 493 // Update the functions literal and return the boilerplate.
493 literals->set(literals_index, *object); 494 literals->set(literals_index, *object);
494 return *object; 495 return *object;
495 } 496 }
496 497
497 498
498 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) { 499 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
499 HandleScope scope(isolate); 500 HandleScope scope(isolate);
500 ASSERT(args.length() == 4); 501 ASSERT(args.length() == 4);
501 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 502 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
502 CONVERT_SMI_CHECKED(literals_index, args[1]); 503 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
503 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); 504 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
504 CONVERT_SMI_CHECKED(flags, args[3]); 505 CONVERT_SMI_ARG_CHECKED(flags, 3);
505 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; 506 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
506 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; 507 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
507 508
508 // Check if boilerplate exists. If not, create it first. 509 // Check if boilerplate exists. If not, create it first.
509 Handle<Object> boilerplate(literals->get(literals_index), isolate); 510 Handle<Object> boilerplate(literals->get(literals_index), isolate);
510 if (*boilerplate == isolate->heap()->undefined_value()) { 511 if (*boilerplate == isolate->heap()->undefined_value()) {
511 boilerplate = CreateObjectLiteralBoilerplate(isolate, 512 boilerplate = CreateObjectLiteralBoilerplate(isolate,
512 literals, 513 literals,
513 constant_properties, 514 constant_properties,
514 should_have_fast_elements, 515 should_have_fast_elements,
515 has_function_literal); 516 has_function_literal);
516 if (boilerplate.is_null()) return Failure::Exception(); 517 if (boilerplate.is_null()) return Failure::Exception();
517 // Update the functions literal and return the boilerplate. 518 // Update the functions literal and return the boilerplate.
518 literals->set(literals_index, *boilerplate); 519 literals->set(literals_index, *boilerplate);
519 } 520 }
520 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); 521 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
521 } 522 }
522 523
523 524
524 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) { 525 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
525 HandleScope scope(isolate); 526 HandleScope scope(isolate);
526 ASSERT(args.length() == 4); 527 ASSERT(args.length() == 4);
527 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 528 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
528 CONVERT_SMI_CHECKED(literals_index, args[1]); 529 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
529 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); 530 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
530 CONVERT_SMI_CHECKED(flags, args[3]); 531 CONVERT_SMI_ARG_CHECKED(flags, 3);
531 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; 532 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
532 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; 533 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
533 534
534 // Check if boilerplate exists. If not, create it first. 535 // Check if boilerplate exists. If not, create it first.
535 Handle<Object> boilerplate(literals->get(literals_index), isolate); 536 Handle<Object> boilerplate(literals->get(literals_index), isolate);
536 if (*boilerplate == isolate->heap()->undefined_value()) { 537 if (*boilerplate == isolate->heap()->undefined_value()) {
537 boilerplate = CreateObjectLiteralBoilerplate(isolate, 538 boilerplate = CreateObjectLiteralBoilerplate(isolate,
538 literals, 539 literals,
539 constant_properties, 540 constant_properties,
540 should_have_fast_elements, 541 should_have_fast_elements,
541 has_function_literal); 542 has_function_literal);
542 if (boilerplate.is_null()) return Failure::Exception(); 543 if (boilerplate.is_null()) return Failure::Exception();
543 // Update the functions literal and return the boilerplate. 544 // Update the functions literal and return the boilerplate.
544 literals->set(literals_index, *boilerplate); 545 literals->set(literals_index, *boilerplate);
545 } 546 }
546 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); 547 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
547 } 548 }
548 549
549 550
550 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) { 551 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
551 HandleScope scope(isolate); 552 HandleScope scope(isolate);
552 ASSERT(args.length() == 3); 553 ASSERT(args.length() == 3);
553 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 554 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
554 CONVERT_SMI_CHECKED(literals_index, args[1]); 555 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
555 CONVERT_ARG_CHECKED(FixedArray, elements, 2); 556 CONVERT_ARG_CHECKED(FixedArray, elements, 2);
556 557
557 // Check if boilerplate exists. If not, create it first. 558 // Check if boilerplate exists. If not, create it first.
558 Handle<Object> boilerplate(literals->get(literals_index), isolate); 559 Handle<Object> boilerplate(literals->get(literals_index), isolate);
559 if (*boilerplate == isolate->heap()->undefined_value()) { 560 if (*boilerplate == isolate->heap()->undefined_value()) {
560 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements); 561 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements);
561 if (boilerplate.is_null()) return Failure::Exception(); 562 if (boilerplate.is_null()) return Failure::Exception();
562 // Update the functions literal and return the boilerplate. 563 // Update the functions literal and return the boilerplate.
563 literals->set(literals_index, *boilerplate); 564 literals->set(literals_index, *boilerplate);
564 } 565 }
565 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); 566 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate));
566 } 567 }
567 568
568 569
569 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) { 570 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
570 HandleScope scope(isolate); 571 HandleScope scope(isolate);
571 ASSERT(args.length() == 3); 572 ASSERT(args.length() == 3);
572 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 573 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
573 CONVERT_SMI_CHECKED(literals_index, args[1]); 574 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
574 CONVERT_ARG_CHECKED(FixedArray, elements, 2); 575 CONVERT_ARG_CHECKED(FixedArray, elements, 2);
575 576
576 // Check if boilerplate exists. If not, create it first. 577 // Check if boilerplate exists. If not, create it first.
577 Handle<Object> boilerplate(literals->get(literals_index), isolate); 578 Handle<Object> boilerplate(literals->get(literals_index), isolate);
578 if (*boilerplate == isolate->heap()->undefined_value()) { 579 if (*boilerplate == isolate->heap()->undefined_value()) {
579 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements); 580 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements);
580 if (boilerplate.is_null()) return Failure::Exception(); 581 if (boilerplate.is_null()) return Failure::Exception();
581 // Update the functions literal and return the boilerplate. 582 // Update the functions literal and return the boilerplate.
582 literals->set(literals_index, *boilerplate); 583 literals->set(literals_index, *boilerplate);
583 } 584 }
584 if (JSObject::cast(*boilerplate)->elements()->map() == 585 if (JSObject::cast(*boilerplate)->elements()->map() ==
585 isolate->heap()->fixed_cow_array_map()) { 586 isolate->heap()->fixed_cow_array_map()) {
586 isolate->counters()->cow_arrays_created_runtime()->Increment(); 587 isolate->counters()->cow_arrays_created_runtime()->Increment();
587 } 588 }
588 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); 589 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
589 } 590 }
590 591
591 592
592 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { 593 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
593 ASSERT(args.length() == 2); 594 ASSERT(args.length() == 2);
594 Object* handler = args[0]; 595 Object* handler = args[0];
595 Object* prototype = args[1]; 596 Object* prototype = args[1];
596 Object* used_prototype = 597 Object* used_prototype =
597 (prototype->IsJSObject() || prototype->IsJSProxy()) ? prototype 598 prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
598 : isolate->heap()->null_value();
599 return isolate->heap()->AllocateJSProxy(handler, used_prototype); 599 return isolate->heap()->AllocateJSProxy(handler, used_prototype);
600 } 600 }
601 601
602 602
603 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) { 603 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
604 ASSERT(args.length() == 2); 604 ASSERT(args.length() == 1);
605 CONVERT_CHECKED(String, key, args[0]); 605 Object* obj = args[0];
606 Object* value = args[1]; 606 return obj->IsJSProxy()
607 RUNTIME_ASSERT(!value->IsFailure()); 607 ? isolate->heap()->true_value() : isolate->heap()->false_value();
608 // Create a catch context extension object. 608 }
609 JSFunction* constructor = 609
610 isolate->context()->global_context()-> 610
611 context_extension_function(); 611 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
612 Object* object; 612 ASSERT(args.length() == 1);
613 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor); 613 CONVERT_CHECKED(JSProxy, proxy, args[0]);
614 if (!maybe_object->ToObject(&object)) return maybe_object; 614 return proxy->handler();
615 }
616 // Assign the exception value to the catch variable and make sure
617 // that the catch variable is DontDelete.
618 { MaybeObject* maybe_value =
619 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
620 JSObject::cast(object)->SetProperty(
621 key, value, DONT_DELETE, kNonStrictMode);
622 if (!maybe_value->ToObject(&value)) return maybe_value;
623 }
624 return object;
625 } 615 }
626 616
627 617
628 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { 618 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
629 NoHandleAllocation ha; 619 NoHandleAllocation ha;
630 ASSERT(args.length() == 1); 620 ASSERT(args.length() == 1);
631 Object* obj = args[0]; 621 Object* obj = args[0];
632 if (!obj->IsJSObject()) return isolate->heap()->null_value(); 622 if (!obj->IsJSObject()) return isolate->heap()->null_value();
633 return JSObject::cast(obj)->class_name(); 623 return JSObject::cast(obj)->class_name();
634 } 624 }
635 625
636 626
627 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
628 NoHandleAllocation ha;
629 ASSERT(args.length() == 1);
630 Object* obj = args[0];
631 do {
632 obj = obj->GetPrototype();
633 } while (obj->IsJSObject() &&
634 JSObject::cast(obj)->map()->is_hidden_prototype());
635 return obj;
636 }
637
638
637 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { 639 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
638 NoHandleAllocation ha; 640 NoHandleAllocation ha;
639 ASSERT(args.length() == 2); 641 ASSERT(args.length() == 2);
640 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). 642 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
641 Object* O = args[0]; 643 Object* O = args[0];
642 Object* V = args[1]; 644 Object* V = args[1];
643 while (true) { 645 while (true) {
644 Object* prototype = V->GetPrototype(); 646 Object* prototype = V->GetPrototype();
645 if (prototype->IsNull()) return isolate->heap()->false_value(); 647 if (prototype->IsNull()) return isolate->heap()->false_value();
646 if (O == prototype) return isolate->heap()->true_value(); 648 if (O == prototype) return isolate->heap()->true_value();
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 } 869 }
868 870
869 case JSObject::DICTIONARY_ELEMENT: { 871 case JSObject::DICTIONARY_ELEMENT: {
870 Handle<JSObject> holder = obj; 872 Handle<JSObject> holder = obj;
871 if (obj->IsJSGlobalProxy()) { 873 if (obj->IsJSGlobalProxy()) {
872 Object* proto = obj->GetPrototype(); 874 Object* proto = obj->GetPrototype();
873 if (proto->IsNull()) return heap->undefined_value(); 875 if (proto->IsNull()) return heap->undefined_value();
874 ASSERT(proto->IsJSGlobalObject()); 876 ASSERT(proto->IsJSGlobalObject());
875 holder = Handle<JSObject>(JSObject::cast(proto)); 877 holder = Handle<JSObject>(JSObject::cast(proto));
876 } 878 }
877 NumberDictionary* dictionary = holder->element_dictionary(); 879 FixedArray* elements = FixedArray::cast(holder->elements());
880 NumberDictionary* dictionary = NULL;
881 if (elements->map() == heap->non_strict_arguments_elements_map()) {
882 dictionary = NumberDictionary::cast(elements->get(1));
883 } else {
884 dictionary = NumberDictionary::cast(elements);
885 }
878 int entry = dictionary->FindEntry(index); 886 int entry = dictionary->FindEntry(index);
879 ASSERT(entry != NumberDictionary::kNotFound); 887 ASSERT(entry != NumberDictionary::kNotFound);
880 PropertyDetails details = dictionary->DetailsAt(entry); 888 PropertyDetails details = dictionary->DetailsAt(entry);
881 switch (details.type()) { 889 switch (details.type()) {
882 case CALLBACKS: { 890 case CALLBACKS: {
883 // This is an accessor property with getter and/or setter. 891 // This is an accessor property with getter and/or setter.
884 FixedArray* callbacks = 892 FixedArray* callbacks =
885 FixedArray::cast(dictionary->ValueAt(entry)); 893 FixedArray::cast(dictionary->ValueAt(entry));
886 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); 894 elms->set(IS_ACCESSOR_INDEX, heap->true_value());
887 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { 895 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 1085
1078 1086
1079 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { 1087 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
1080 ASSERT(args.length() == 4); 1088 ASSERT(args.length() == 4);
1081 HandleScope scope(isolate); 1089 HandleScope scope(isolate);
1082 Handle<GlobalObject> global = Handle<GlobalObject>( 1090 Handle<GlobalObject> global = Handle<GlobalObject>(
1083 isolate->context()->global()); 1091 isolate->context()->global());
1084 1092
1085 Handle<Context> context = args.at<Context>(0); 1093 Handle<Context> context = args.at<Context>(0);
1086 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); 1094 CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
1087 bool is_eval = Smi::cast(args[2])->value() == 1; 1095 bool is_eval = args.smi_at(2) == 1;
1088 StrictModeFlag strict_mode = 1096 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
1089 static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
1090 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); 1097 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1091 1098
1092 // Compute the property attributes. According to ECMA-262, section 1099 // Compute the property attributes. According to ECMA-262, section
1093 // 13, page 71, the property must be read-only and 1100 // 13, page 71, the property must be read-only and
1094 // non-deletable. However, neither SpiderMonkey nor KJS creates the 1101 // non-deletable. However, neither SpiderMonkey nor KJS creates the
1095 // property as read-only, so we don't either. 1102 // property as read-only, so we don't either.
1096 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; 1103 PropertyAttributes base = is_eval ? NONE : DONT_DELETE;
1097 1104
1098 // Traverse the name/value pairs and set the properties. 1105 // Traverse the name/value pairs and set the properties.
1099 int length = pairs->length(); 1106 int length = pairs->length();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 return isolate->heap()->undefined_value(); 1225 return isolate->heap()->undefined_value();
1219 } 1226 }
1220 1227
1221 1228
1222 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { 1229 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1223 HandleScope scope(isolate); 1230 HandleScope scope(isolate);
1224 ASSERT(args.length() == 4); 1231 ASSERT(args.length() == 4);
1225 1232
1226 CONVERT_ARG_CHECKED(Context, context, 0); 1233 CONVERT_ARG_CHECKED(Context, context, 0);
1227 Handle<String> name(String::cast(args[1])); 1234 Handle<String> name(String::cast(args[1]));
1228 PropertyAttributes mode = 1235 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1229 static_cast<PropertyAttributes>(Smi::cast(args[2])->value());
1230 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); 1236 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1231 Handle<Object> initial_value(args[3], isolate); 1237 Handle<Object> initial_value(args[3], isolate);
1232 1238
1233 // Declarations are always done in the function context. 1239 // Declarations are always done in a function or global context.
1234 context = Handle<Context>(context->fcontext()); 1240 context = Handle<Context>(context->declaration_context());
1235 1241
1236 int index; 1242 int index;
1237 PropertyAttributes attributes; 1243 PropertyAttributes attributes;
1238 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; 1244 ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1239 Handle<Object> holder = 1245 Handle<Object> holder =
1240 context->Lookup(name, flags, &index, &attributes); 1246 context->Lookup(name, flags, &index, &attributes);
1241 1247
1242 if (attributes != ABSENT) { 1248 if (attributes != ABSENT) {
1243 // The name was declared before; check for conflicting 1249 // The name was declared before; check for conflicting
1244 // re-declarations: This is similar to the code in parser.cc in 1250 // re-declarations: This is similar to the code in parser.cc in
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 } 1284 }
1279 } 1285 }
1280 1286
1281 } else { 1287 } else {
1282 // The property is not in the function context. It needs to be 1288 // The property is not in the function context. It needs to be
1283 // "declared" in the function context's extension context, or in the 1289 // "declared" in the function context's extension context, or in the
1284 // global context. 1290 // global context.
1285 Handle<JSObject> context_ext; 1291 Handle<JSObject> context_ext;
1286 if (context->has_extension()) { 1292 if (context->has_extension()) {
1287 // The function context's extension context exists - use it. 1293 // The function context's extension context exists - use it.
1288 context_ext = Handle<JSObject>(context->extension()); 1294 context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1289 } else { 1295 } else {
1290 // The function context's extension context does not exists - allocate 1296 // The function context's extension context does not exists - allocate
1291 // it. 1297 // it.
1292 context_ext = isolate->factory()->NewJSObject( 1298 context_ext = isolate->factory()->NewJSObject(
1293 isolate->context_extension_function()); 1299 isolate->context_extension_function());
1294 // And store it in the extension slot. 1300 // And store it in the extension slot.
1295 context->set_extension(*context_ext); 1301 context->set_extension(*context_ext);
1296 } 1302 }
1297 ASSERT(*context_ext != NULL); 1303 ASSERT(*context_ext != NULL);
1298 1304
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 // args[2] == value (optional) 1338 // args[2] == value (optional)
1333 1339
1334 // Determine if we need to assign to the variable if it already 1340 // Determine if we need to assign to the variable if it already
1335 // exists (based on the number of arguments). 1341 // exists (based on the number of arguments).
1336 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); 1342 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
1337 bool assign = args.length() == 3; 1343 bool assign = args.length() == 3;
1338 1344
1339 CONVERT_ARG_CHECKED(String, name, 0); 1345 CONVERT_ARG_CHECKED(String, name, 0);
1340 GlobalObject* global = isolate->context()->global(); 1346 GlobalObject* global = isolate->context()->global();
1341 RUNTIME_ASSERT(args[1]->IsSmi()); 1347 RUNTIME_ASSERT(args[1]->IsSmi());
1342 StrictModeFlag strict_mode = 1348 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1));
1343 static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
1344 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); 1349 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1345 1350
1346 // According to ECMA-262, section 12.2, page 62, the property must 1351 // According to ECMA-262, section 12.2, page 62, the property must
1347 // not be deletable. 1352 // not be deletable.
1348 PropertyAttributes attributes = DONT_DELETE; 1353 PropertyAttributes attributes = DONT_DELETE;
1349 1354
1350 // Lookup the property locally in the global object. If it isn't 1355 // Lookup the property locally in the global object. If it isn't
1351 // there, there is a property with this name in the prototype chain. 1356 // there, there is a property with this name in the prototype chain.
1352 // We follow Safari and Firefox behavior and only set the property 1357 // We follow Safari and Firefox behavior and only set the property
1353 // locally if there is an explicit initialization value that we have 1358 // locally if there is an explicit initialization value that we have
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 1517
1513 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { 1518 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1514 HandleScope scope(isolate); 1519 HandleScope scope(isolate);
1515 ASSERT(args.length() == 3); 1520 ASSERT(args.length() == 3);
1516 1521
1517 Handle<Object> value(args[0], isolate); 1522 Handle<Object> value(args[0], isolate);
1518 ASSERT(!value->IsTheHole()); 1523 ASSERT(!value->IsTheHole());
1519 CONVERT_ARG_CHECKED(Context, context, 1); 1524 CONVERT_ARG_CHECKED(Context, context, 1);
1520 Handle<String> name(String::cast(args[2])); 1525 Handle<String> name(String::cast(args[2]));
1521 1526
1522 // Initializations are always done in the function context. 1527 // Initializations are always done in a function or global context.
1523 context = Handle<Context>(context->fcontext()); 1528 context = Handle<Context>(context->declaration_context());
1524 1529
1525 int index; 1530 int index;
1526 PropertyAttributes attributes; 1531 PropertyAttributes attributes;
1527 ContextLookupFlags flags = FOLLOW_CHAINS; 1532 ContextLookupFlags flags = FOLLOW_CHAINS;
1528 Handle<Object> holder = 1533 Handle<Object> holder =
1529 context->Lookup(name, flags, &index, &attributes); 1534 context->Lookup(name, flags, &index, &attributes);
1530 1535
1531 // In most situations, the property introduced by the const 1536 // In most situations, the property introduced by the const
1532 // declaration should be present in the context extension object. 1537 // declaration should be present in the context extension object.
1533 // However, because declaration and initialization are separate, the 1538 // However, because declaration and initialization are separate, the
1534 // property might have been deleted (if it was introduced by eval) 1539 // property might have been deleted (if it was introduced by eval)
1535 // before we reach the initialization point. 1540 // before we reach the initialization point.
1536 // 1541 //
1537 // Example: 1542 // Example:
1538 // 1543 //
1539 // function f() { eval("delete x; const x;"); } 1544 // function f() { eval("delete x; const x;"); }
1540 // 1545 //
1541 // In that case, the initialization behaves like a normal assignment 1546 // In that case, the initialization behaves like a normal assignment
1542 // to property 'x'. 1547 // to property 'x'.
1543 if (index >= 0) { 1548 if (index >= 0) {
1544 // Property was found in a context.
1545 if (holder->IsContext()) { 1549 if (holder->IsContext()) {
1546 // The holder cannot be the function context. If it is, there 1550 // Property was found in a context. Perform the assignment if we
1547 // should have been a const redeclaration error when declaring 1551 // found some non-constant or an uninitialized constant.
1548 // the const property. 1552 Handle<Context> context = Handle<Context>::cast(holder);
1549 ASSERT(!holder.is_identical_to(context)); 1553 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1550 if ((attributes & READ_ONLY) == 0) { 1554 context->set(index, *value);
1551 Handle<Context>::cast(holder)->set(index, *value);
1552 } 1555 }
1553 } else { 1556 } else {
1554 // The holder is an arguments object. 1557 // The holder is an arguments object.
1555 ASSERT((attributes & READ_ONLY) == 0); 1558 ASSERT((attributes & READ_ONLY) == 0);
1556 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); 1559 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1557 RETURN_IF_EMPTY_HANDLE( 1560 RETURN_IF_EMPTY_HANDLE(
1558 isolate, 1561 isolate,
1559 SetElement(arguments, index, value, kNonStrictMode)); 1562 SetElement(arguments, index, value, kNonStrictMode));
1560 } 1563 }
1561 return *value; 1564 return *value;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 1618
1616 return *value; 1619 return *value;
1617 } 1620 }
1618 1621
1619 1622
1620 RUNTIME_FUNCTION(MaybeObject*, 1623 RUNTIME_FUNCTION(MaybeObject*,
1621 Runtime_OptimizeObjectForAddingMultipleProperties) { 1624 Runtime_OptimizeObjectForAddingMultipleProperties) {
1622 HandleScope scope(isolate); 1625 HandleScope scope(isolate);
1623 ASSERT(args.length() == 2); 1626 ASSERT(args.length() == 2);
1624 CONVERT_ARG_CHECKED(JSObject, object, 0); 1627 CONVERT_ARG_CHECKED(JSObject, object, 0);
1625 CONVERT_SMI_CHECKED(properties, args[1]); 1628 CONVERT_SMI_ARG_CHECKED(properties, 1);
1626 if (object->HasFastProperties()) { 1629 if (object->HasFastProperties()) {
1627 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); 1630 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1628 } 1631 }
1629 return *object; 1632 return *object;
1630 } 1633 }
1631 1634
1632 1635
1633 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { 1636 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1634 HandleScope scope(isolate); 1637 HandleScope scope(isolate);
1635 ASSERT(args.length() == 4); 1638 ASSERT(args.length() == 4);
1636 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 1639 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
1637 CONVERT_ARG_CHECKED(String, subject, 1); 1640 CONVERT_ARG_CHECKED(String, subject, 1);
1638 // Due to the way the JS calls are constructed this must be less than the 1641 // Due to the way the JS calls are constructed this must be less than the
1639 // length of a string, i.e. it is always a Smi. We check anyway for security. 1642 // length of a string, i.e. it is always a Smi. We check anyway for security.
1640 CONVERT_SMI_CHECKED(index, args[2]); 1643 CONVERT_SMI_ARG_CHECKED(index, 2);
1641 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 1644 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1642 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1645 RUNTIME_ASSERT(last_match_info->HasFastElements());
1643 RUNTIME_ASSERT(index >= 0); 1646 RUNTIME_ASSERT(index >= 0);
1644 RUNTIME_ASSERT(index <= subject->length()); 1647 RUNTIME_ASSERT(index <= subject->length());
1645 isolate->counters()->regexp_entry_runtime()->Increment(); 1648 isolate->counters()->regexp_entry_runtime()->Increment();
1646 Handle<Object> result = RegExpImpl::Exec(regexp, 1649 Handle<Object> result = RegExpImpl::Exec(regexp,
1647 subject, 1650 subject,
1648 index, 1651 index,
1649 last_match_info); 1652 last_match_info);
1650 if (result.is_null()) return Failure::Exception(); 1653 if (result.is_null()) return Failure::Exception();
1651 return *result; 1654 return *result;
1652 } 1655 }
1653 1656
1654 1657
1655 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) { 1658 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
1656 ASSERT(args.length() == 3); 1659 ASSERT(args.length() == 3);
1657 CONVERT_SMI_CHECKED(elements_count, args[0]); 1660 CONVERT_SMI_ARG_CHECKED(elements_count, 0);
1658 if (elements_count > JSArray::kMaxFastElementsLength) { 1661 if (elements_count > JSArray::kMaxFastElementsLength) {
1659 return isolate->ThrowIllegalOperation(); 1662 return isolate->ThrowIllegalOperation();
1660 } 1663 }
1661 Object* new_object; 1664 Object* new_object;
1662 { MaybeObject* maybe_new_object = 1665 { MaybeObject* maybe_new_object =
1663 isolate->heap()->AllocateFixedArrayWithHoles(elements_count); 1666 isolate->heap()->AllocateFixedArrayWithHoles(elements_count);
1664 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; 1667 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
1665 } 1668 }
1666 FixedArray* elements = FixedArray::cast(new_object); 1669 FixedArray* elements = FixedArray::cast(new_object);
1667 { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw( 1670 { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1802 Context* global_context = 1805 Context* global_context =
1803 isolate->context()->global()->global_context(); 1806 isolate->context()->global()->global_context();
1804 return global_context->global()->global_receiver(); 1807 return global_context->global()->global_receiver();
1805 } 1808 }
1806 1809
1807 1810
1808 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) { 1811 RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
1809 HandleScope scope(isolate); 1812 HandleScope scope(isolate);
1810 ASSERT(args.length() == 4); 1813 ASSERT(args.length() == 4);
1811 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 1814 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
1812 int index = Smi::cast(args[1])->value(); 1815 int index = args.smi_at(1);
1813 Handle<String> pattern = args.at<String>(2); 1816 Handle<String> pattern = args.at<String>(2);
1814 Handle<String> flags = args.at<String>(3); 1817 Handle<String> flags = args.at<String>(3);
1815 1818
1816 // Get the RegExp function from the context in the literals array. 1819 // Get the RegExp function from the context in the literals array.
1817 // This is the RegExp function from the context in which the 1820 // This is the RegExp function from the context in which the
1818 // function was created. We do not use the RegExp function from the 1821 // function was created. We do not use the RegExp function from the
1819 // current global context because this might be the RegExp function 1822 // current global context because this might be the RegExp function
1820 // from another context which we should not have access to. 1823 // from another context which we should not have access to.
1821 Handle<JSFunction> constructor = 1824 Handle<JSFunction> constructor =
1822 Handle<JSFunction>( 1825 Handle<JSFunction>(
(...skipping 25 matching lines...) Expand all
1848 NoHandleAllocation ha; 1851 NoHandleAllocation ha;
1849 ASSERT(args.length() == 2); 1852 ASSERT(args.length() == 2);
1850 1853
1851 CONVERT_CHECKED(JSFunction, f, args[0]); 1854 CONVERT_CHECKED(JSFunction, f, args[0]);
1852 CONVERT_CHECKED(String, name, args[1]); 1855 CONVERT_CHECKED(String, name, args[1]);
1853 f->shared()->set_name(name); 1856 f->shared()->set_name(name);
1854 return isolate->heap()->undefined_value(); 1857 return isolate->heap()->undefined_value();
1855 } 1858 }
1856 1859
1857 1860
1861 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
1862 HandleScope scope(isolate);
1863 ASSERT(args.length() == 1);
1864
1865 CONVERT_CHECKED(JSFunction, fun, args[0]);
1866 fun->shared()->set_bound(true);
1867 return isolate->heap()->undefined_value();
1868 }
1869
1858 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) { 1870 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
1859 NoHandleAllocation ha; 1871 NoHandleAllocation ha;
1860 ASSERT(args.length() == 1); 1872 ASSERT(args.length() == 1);
1861 1873
1862 CONVERT_CHECKED(JSFunction, f, args[0]); 1874 CONVERT_CHECKED(JSFunction, f, args[0]);
1863 Object* obj = f->RemovePrototype(); 1875 Object* obj = f->RemovePrototype();
1864 if (obj->IsFailure()) return obj; 1876 if (obj->IsFailure()) return obj;
1865 1877
1866 return isolate->heap()->undefined_value(); 1878 return isolate->heap()->undefined_value();
1867 } 1879 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 2040
2029 target->set_context(*context); 2041 target->set_context(*context);
2030 return *target; 2042 return *target;
2031 } 2043 }
2032 2044
2033 2045
2034 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) { 2046 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
2035 HandleScope scope(isolate); 2047 HandleScope scope(isolate);
2036 ASSERT(args.length() == 2); 2048 ASSERT(args.length() == 2);
2037 CONVERT_ARG_CHECKED(JSFunction, function, 0); 2049 CONVERT_ARG_CHECKED(JSFunction, function, 0);
2038 CONVERT_SMI_CHECKED(num, args[1]); 2050 CONVERT_SMI_ARG_CHECKED(num, 1);
2039 RUNTIME_ASSERT(num >= 0); 2051 RUNTIME_ASSERT(num >= 0);
2040 SetExpectedNofProperties(function, num); 2052 SetExpectedNofProperties(function, num);
2041 return isolate->heap()->undefined_value(); 2053 return isolate->heap()->undefined_value();
2042 } 2054 }
2043 2055
2044 2056
2045 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, 2057 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
2046 Object* char_code) { 2058 Object* char_code) {
2047 uint32_t code; 2059 uint32_t code;
2048 if (char_code->ToArrayIndex(&code)) { 2060 if (char_code->ToArrayIndex(&code)) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 } 2264 }
2253 2265
2254 2266
2255 Handle<String> ToString() { 2267 Handle<String> ToString() {
2256 if (array_builder_.length() == 0) { 2268 if (array_builder_.length() == 0) {
2257 return heap_->isolate()->factory()->empty_string(); 2269 return heap_->isolate()->factory()->empty_string();
2258 } 2270 }
2259 2271
2260 Handle<String> joined_string; 2272 Handle<String> joined_string;
2261 if (is_ascii_) { 2273 if (is_ascii_) {
2262 joined_string = NewRawAsciiString(character_count_); 2274 Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_);
2263 AssertNoAllocation no_alloc; 2275 AssertNoAllocation no_alloc;
2264 SeqAsciiString* seq = SeqAsciiString::cast(*joined_string);
2265 char* char_buffer = seq->GetChars(); 2276 char* char_buffer = seq->GetChars();
2266 StringBuilderConcatHelper(*subject_, 2277 StringBuilderConcatHelper(*subject_,
2267 char_buffer, 2278 char_buffer,
2268 *array_builder_.array(), 2279 *array_builder_.array(),
2269 array_builder_.length()); 2280 array_builder_.length());
2281 joined_string = Handle<String>::cast(seq);
2270 } else { 2282 } else {
2271 // Non-ASCII. 2283 // Non-ASCII.
2272 joined_string = NewRawTwoByteString(character_count_); 2284 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
2273 AssertNoAllocation no_alloc; 2285 AssertNoAllocation no_alloc;
2274 SeqTwoByteString* seq = SeqTwoByteString::cast(*joined_string);
2275 uc16* char_buffer = seq->GetChars(); 2286 uc16* char_buffer = seq->GetChars();
2276 StringBuilderConcatHelper(*subject_, 2287 StringBuilderConcatHelper(*subject_,
2277 char_buffer, 2288 char_buffer,
2278 *array_builder_.array(), 2289 *array_builder_.array(),
2279 array_builder_.length()); 2290 array_builder_.length());
2291 joined_string = Handle<String>::cast(seq);
2280 } 2292 }
2281 return joined_string; 2293 return joined_string;
2282 } 2294 }
2283 2295
2284 2296
2285 void IncrementCharacterCount(int by) { 2297 void IncrementCharacterCount(int by) {
2286 if (character_count_ > String::kMaxLength - by) { 2298 if (character_count_ > String::kMaxLength - by) {
2287 V8::FatalProcessOutOfMemory("String.replace result too large."); 2299 V8::FatalProcessOutOfMemory("String.replace result too large.");
2288 } 2300 }
2289 character_count_ += by; 2301 character_count_ += by;
2290 } 2302 }
2291 2303
2292 Handle<JSArray> GetParts() { 2304 Handle<JSArray> GetParts() {
2293 return array_builder_.ToJSArray(); 2305 return array_builder_.ToJSArray();
2294 } 2306 }
2295 2307
2296 private: 2308 private:
2297 Handle<String> NewRawAsciiString(int size) { 2309 Handle<SeqAsciiString> NewRawAsciiString(int length) {
2298 CALL_HEAP_FUNCTION(heap_->isolate(), 2310 return heap_->isolate()->factory()->NewRawAsciiString(length);
2299 heap_->AllocateRawAsciiString(size), String);
2300 } 2311 }
2301 2312
2302 2313
2303 Handle<String> NewRawTwoByteString(int size) { 2314 Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
2304 CALL_HEAP_FUNCTION(heap_->isolate(), 2315 return heap_->isolate()->factory()->NewRawTwoByteString(length);
2305 heap_->AllocateRawTwoByteString(size), String);
2306 } 2316 }
2307 2317
2308 2318
2309 void AddElement(Object* element) { 2319 void AddElement(Object* element) {
2310 ASSERT(element->IsSmi() || element->IsString()); 2320 ASSERT(element->IsSmi() || element->IsString());
2311 ASSERT(array_builder_.capacity() > array_builder_.length()); 2321 ASSERT(array_builder_.capacity() > array_builder_.length());
2312 array_builder_.Add(element); 2322 array_builder_.Add(element);
2313 } 2323 }
2314 2324
2315 Heap* heap_; 2325 Heap* heap_;
(...skipping 15 matching lines...) Expand all
2331 2341
2332 void Apply(ReplacementStringBuilder* builder, 2342 void Apply(ReplacementStringBuilder* builder,
2333 int match_from, 2343 int match_from,
2334 int match_to, 2344 int match_to,
2335 Handle<JSArray> last_match_info); 2345 Handle<JSArray> last_match_info);
2336 2346
2337 // Number of distinct parts of the replacement pattern. 2347 // Number of distinct parts of the replacement pattern.
2338 int parts() { 2348 int parts() {
2339 return parts_.length(); 2349 return parts_.length();
2340 } 2350 }
2351
2341 private: 2352 private:
2342 enum PartType { 2353 enum PartType {
2343 SUBJECT_PREFIX = 1, 2354 SUBJECT_PREFIX = 1,
2344 SUBJECT_SUFFIX, 2355 SUBJECT_SUFFIX,
2345 SUBJECT_CAPTURE, 2356 SUBJECT_CAPTURE,
2346 REPLACEMENT_SUBSTRING, 2357 REPLACEMENT_SUBSTRING,
2347 REPLACEMENT_STRING, 2358 REPLACEMENT_STRING,
2348 2359
2349 NUMBER_OF_PART_TYPES 2360 NUMBER_OF_PART_TYPES
2350 }; 2361 };
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 if (match.is_null()) { 2618 if (match.is_null()) {
2608 return Failure::Exception(); 2619 return Failure::Exception();
2609 } 2620 }
2610 if (match->IsNull()) { 2621 if (match->IsNull()) {
2611 return *subject_handle; 2622 return *subject_handle;
2612 } 2623 }
2613 2624
2614 int capture_count = regexp_handle->CaptureCount(); 2625 int capture_count = regexp_handle->CaptureCount();
2615 2626
2616 // CompiledReplacement uses zone allocation. 2627 // CompiledReplacement uses zone allocation.
2617 CompilationZoneScope zone(isolate, DELETE_ON_EXIT); 2628 ZoneScope zone(isolate, DELETE_ON_EXIT);
2618 CompiledReplacement compiled_replacement; 2629 CompiledReplacement compiled_replacement;
2619 compiled_replacement.Compile(replacement_handle, 2630 compiled_replacement.Compile(replacement_handle,
2620 capture_count, 2631 capture_count,
2621 length); 2632 length);
2622 2633
2623 bool is_global = regexp_handle->GetFlags().is_global(); 2634 bool is_global = regexp_handle->GetFlags().is_global();
2624 2635
2625 // Guessing the number of parts that the final result string is built 2636 // Guessing the number of parts that the final result string is built
2626 // from. Global regexps can match any number of times, so we guess 2637 // from. Global regexps can match any number of times, so we guess
2627 // conservatively. 2638 // conservatively.
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
3084 3095
3085 return Smi::FromInt(str1_length - str2_length); 3096 return Smi::FromInt(str1_length - str2_length);
3086 } 3097 }
3087 3098
3088 3099
3089 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) { 3100 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
3090 NoHandleAllocation ha; 3101 NoHandleAllocation ha;
3091 ASSERT(args.length() == 3); 3102 ASSERT(args.length() == 3);
3092 3103
3093 CONVERT_CHECKED(String, value, args[0]); 3104 CONVERT_CHECKED(String, value, args[0]);
3094 Object* from = args[1];
3095 Object* to = args[2];
3096 int start, end; 3105 int start, end;
3097 // We have a fast integer-only case here to avoid a conversion to double in 3106 // We have a fast integer-only case here to avoid a conversion to double in
3098 // the common case where from and to are Smis. 3107 // the common case where from and to are Smis.
3099 if (from->IsSmi() && to->IsSmi()) { 3108 if (args[1]->IsSmi() && args[2]->IsSmi()) {
3100 start = Smi::cast(from)->value(); 3109 CONVERT_SMI_ARG_CHECKED(from_number, 1);
3101 end = Smi::cast(to)->value(); 3110 CONVERT_SMI_ARG_CHECKED(to_number, 2);
3111 start = from_number;
3112 end = to_number;
3102 } else { 3113 } else {
3103 CONVERT_DOUBLE_CHECKED(from_number, from); 3114 CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
3104 CONVERT_DOUBLE_CHECKED(to_number, to); 3115 CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
3105 start = FastD2I(from_number); 3116 start = FastD2I(from_number);
3106 end = FastD2I(to_number); 3117 end = FastD2I(to_number);
3107 } 3118 }
3108 RUNTIME_ASSERT(end >= start); 3119 RUNTIME_ASSERT(end >= start);
3109 RUNTIME_ASSERT(start >= 0); 3120 RUNTIME_ASSERT(start >= 0);
3110 RUNTIME_ASSERT(end <= value->length()); 3121 RUNTIME_ASSERT(end <= value->length());
3111 isolate->counters()->sub_string_runtime()->Increment(); 3122 isolate->counters()->sub_string_runtime()->Increment();
3112 return value->SubString(start, end); 3123 return value->SubString(start, end);
3113 } 3124 }
3114 3125
3115 3126
3116 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) { 3127 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3117 ASSERT_EQ(3, args.length()); 3128 ASSERT_EQ(3, args.length());
3118 3129
3119 CONVERT_ARG_CHECKED(String, subject, 0); 3130 CONVERT_ARG_CHECKED(String, subject, 0);
3120 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); 3131 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
3121 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2); 3132 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2);
3122 HandleScope handles; 3133 HandleScope handles;
3123 3134
3124 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info); 3135 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info);
3125 3136
3126 if (match.is_null()) { 3137 if (match.is_null()) {
3127 return Failure::Exception(); 3138 return Failure::Exception();
3128 } 3139 }
3129 if (match->IsNull()) { 3140 if (match->IsNull()) {
3130 return isolate->heap()->null_value(); 3141 return isolate->heap()->null_value();
3131 } 3142 }
3132 int length = subject->length(); 3143 int length = subject->length();
3133 3144
3134 CompilationZoneScope zone_space(isolate, DELETE_ON_EXIT); 3145 ZoneScope zone_space(isolate, DELETE_ON_EXIT);
3135 ZoneList<int> offsets(8); 3146 ZoneList<int> offsets(8);
3147 int start;
3148 int end;
3136 do { 3149 do {
3137 int start;
3138 int end;
3139 { 3150 {
3140 AssertNoAllocation no_alloc; 3151 AssertNoAllocation no_alloc;
3141 FixedArray* elements = FixedArray::cast(regexp_info->elements()); 3152 FixedArray* elements = FixedArray::cast(regexp_info->elements());
3142 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); 3153 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
3143 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); 3154 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
3144 } 3155 }
3145 offsets.Add(start); 3156 offsets.Add(start);
3146 offsets.Add(end); 3157 offsets.Add(end);
3147 int index = start < end ? end : end + 1; 3158 if (start == end) if (++end > length) break;
3148 if (index > length) break; 3159 match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
3149 match = RegExpImpl::Exec(regexp, subject, index, regexp_info);
3150 if (match.is_null()) { 3160 if (match.is_null()) {
3151 return Failure::Exception(); 3161 return Failure::Exception();
3152 } 3162 }
3153 } while (!match->IsNull()); 3163 } while (!match->IsNull());
3154 int matches = offsets.length() / 2; 3164 int matches = offsets.length() / 2;
3155 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); 3165 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
3156 for (int i = 0; i < matches ; i++) { 3166 Handle<String> substring = isolate->factory()->
3167 NewSubString(subject, offsets.at(0), offsets.at(1));
3168 elements->set(0, *substring);
3169 for (int i = 1; i < matches ; i++) {
3157 int from = offsets.at(i * 2); 3170 int from = offsets.at(i * 2);
3158 int to = offsets.at(i * 2 + 1); 3171 int to = offsets.at(i * 2 + 1);
3159 Handle<String> match = isolate->factory()->NewSubString(subject, from, to); 3172 Handle<String> substring = isolate->factory()->
3160 elements->set(i, *match); 3173 NewProperSubString(subject, from, to);
3174 elements->set(i, *substring);
3161 } 3175 }
3162 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); 3176 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
3163 result->set_length(Smi::FromInt(matches)); 3177 result->set_length(Smi::FromInt(matches));
3164 return *result; 3178 return *result;
3165 } 3179 }
3166 3180
3167 3181
3168 // Two smis before and after the match, for very long strings. 3182 // Two smis before and after the match, for very long strings.
3169 const int kMaxBuilderEntriesPerRegExpMatch = 5; 3183 const int kMaxBuilderEntriesPerRegExpMatch = 5;
3170 3184
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 ASSERT(subject->IsFlat()); 3314 ASSERT(subject->IsFlat());
3301 int match_start = -1; 3315 int match_start = -1;
3302 int match_end = 0; 3316 int match_end = 0;
3303 int pos = 0; 3317 int pos = 0;
3304 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); 3318 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
3305 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; 3319 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
3306 3320
3307 OffsetsVector registers(required_registers); 3321 OffsetsVector registers(required_registers);
3308 Vector<int32_t> register_vector(registers.vector(), registers.length()); 3322 Vector<int32_t> register_vector(registers.vector(), registers.length());
3309 int subject_length = subject->length(); 3323 int subject_length = subject->length();
3324 bool first = true;
3310 3325
3311 for (;;) { // Break on failure, return on exception. 3326 for (;;) { // Break on failure, return on exception.
3312 RegExpImpl::IrregexpResult result = 3327 RegExpImpl::IrregexpResult result =
3313 RegExpImpl::IrregexpExecOnce(regexp, 3328 RegExpImpl::IrregexpExecOnce(regexp,
3314 subject, 3329 subject,
3315 pos, 3330 pos,
3316 register_vector); 3331 register_vector);
3317 if (result == RegExpImpl::RE_SUCCESS) { 3332 if (result == RegExpImpl::RE_SUCCESS) {
3318 match_start = register_vector[0]; 3333 match_start = register_vector[0];
3319 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); 3334 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3320 if (match_end < match_start) { 3335 if (match_end < match_start) {
3321 ReplacementStringBuilder::AddSubjectSlice(builder, 3336 ReplacementStringBuilder::AddSubjectSlice(builder,
3322 match_end, 3337 match_end,
3323 match_start); 3338 match_start);
3324 } 3339 }
3325 match_end = register_vector[1]; 3340 match_end = register_vector[1];
3326 HandleScope loop_scope(isolate); 3341 HandleScope loop_scope(isolate);
3327 builder->Add(*isolate->factory()->NewSubString(subject, 3342 if (!first) {
3328 match_start, 3343 builder->Add(*isolate->factory()->NewProperSubString(subject,
3329 match_end)); 3344 match_start,
3345 match_end));
3346 } else {
3347 builder->Add(*isolate->factory()->NewSubString(subject,
3348 match_start,
3349 match_end));
3350 }
3330 if (match_start != match_end) { 3351 if (match_start != match_end) {
3331 pos = match_end; 3352 pos = match_end;
3332 } else { 3353 } else {
3333 pos = match_end + 1; 3354 pos = match_end + 1;
3334 if (pos > subject_length) break; 3355 if (pos > subject_length) break;
3335 } 3356 }
3336 } else if (result == RegExpImpl::RE_FAILURE) { 3357 } else if (result == RegExpImpl::RE_FAILURE) {
3337 break; 3358 break;
3338 } else { 3359 } else {
3339 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); 3360 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3340 return result; 3361 return result;
3341 } 3362 }
3363 first = false;
3342 } 3364 }
3343 3365
3344 if (match_start >= 0) { 3366 if (match_start >= 0) {
3345 if (match_end < subject_length) { 3367 if (match_end < subject_length) {
3346 ReplacementStringBuilder::AddSubjectSlice(builder, 3368 ReplacementStringBuilder::AddSubjectSlice(builder,
3347 match_end, 3369 match_end,
3348 subject_length); 3370 subject_length);
3349 } 3371 }
3350 SetLastMatchInfoNoCaptures(subject, 3372 SetLastMatchInfoNoCaptures(subject,
3351 last_match_array, 3373 last_match_array,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3383 3405
3384 // Position to search from. 3406 // Position to search from.
3385 int pos = 0; 3407 int pos = 0;
3386 // End of previous match. Differs from pos if match was empty. 3408 // End of previous match. Differs from pos if match was empty.
3387 int match_end = 0; 3409 int match_end = 0;
3388 if (result == RegExpImpl::RE_SUCCESS) { 3410 if (result == RegExpImpl::RE_SUCCESS) {
3389 // Need to keep a copy of the previous match for creating last_match_info 3411 // Need to keep a copy of the previous match for creating last_match_info
3390 // at the end, so we have two vectors that we swap between. 3412 // at the end, so we have two vectors that we swap between.
3391 OffsetsVector registers2(required_registers); 3413 OffsetsVector registers2(required_registers);
3392 Vector<int> prev_register_vector(registers2.vector(), registers2.length()); 3414 Vector<int> prev_register_vector(registers2.vector(), registers2.length());
3393 3415 bool first = true;
3394 do { 3416 do {
3395 int match_start = register_vector[0]; 3417 int match_start = register_vector[0];
3396 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); 3418 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3397 if (match_end < match_start) { 3419 if (match_end < match_start) {
3398 ReplacementStringBuilder::AddSubjectSlice(builder, 3420 ReplacementStringBuilder::AddSubjectSlice(builder,
3399 match_end, 3421 match_end,
3400 match_start); 3422 match_start);
3401 } 3423 }
3402 match_end = register_vector[1]; 3424 match_end = register_vector[1];
3403 3425
3404 { 3426 {
3405 // Avoid accumulating new handles inside loop. 3427 // Avoid accumulating new handles inside loop.
3406 HandleScope temp_scope(isolate); 3428 HandleScope temp_scope(isolate);
3407 // Arguments array to replace function is match, captures, index and 3429 // Arguments array to replace function is match, captures, index and
3408 // subject, i.e., 3 + capture count in total. 3430 // subject, i.e., 3 + capture count in total.
3409 Handle<FixedArray> elements = 3431 Handle<FixedArray> elements =
3410 isolate->factory()->NewFixedArray(3 + capture_count); 3432 isolate->factory()->NewFixedArray(3 + capture_count);
3411 Handle<String> match = isolate->factory()->NewSubString(subject, 3433 Handle<String> match;
3412 match_start, 3434 if (!first) {
3413 match_end); 3435 match = isolate->factory()->NewProperSubString(subject,
3436 match_start,
3437 match_end);
3438 } else {
3439 match = isolate->factory()->NewSubString(subject,
3440 match_start,
3441 match_end);
3442 }
3414 elements->set(0, *match); 3443 elements->set(0, *match);
3415 for (int i = 1; i <= capture_count; i++) { 3444 for (int i = 1; i <= capture_count; i++) {
3416 int start = register_vector[i * 2]; 3445 int start = register_vector[i * 2];
3417 if (start >= 0) { 3446 if (start >= 0) {
3418 int end = register_vector[i * 2 + 1]; 3447 int end = register_vector[i * 2 + 1];
3419 ASSERT(start <= end); 3448 ASSERT(start <= end);
3420 Handle<String> substring = isolate->factory()->NewSubString(subject, 3449 Handle<String> substring;
3421 start, 3450 if (!first) {
3422 end); 3451 substring = isolate->factory()->NewProperSubString(subject,
3452 start,
3453 end);
3454 } else {
3455 substring = isolate->factory()->NewSubString(subject, start, end);
3456 }
3423 elements->set(i, *substring); 3457 elements->set(i, *substring);
3424 } else { 3458 } else {
3425 ASSERT(register_vector[i * 2 + 1] < 0); 3459 ASSERT(register_vector[i * 2 + 1] < 0);
3426 elements->set(i, isolate->heap()->undefined_value()); 3460 elements->set(i, isolate->heap()->undefined_value());
3427 } 3461 }
3428 } 3462 }
3429 elements->set(capture_count + 1, Smi::FromInt(match_start)); 3463 elements->set(capture_count + 1, Smi::FromInt(match_start));
3430 elements->set(capture_count + 2, *subject); 3464 elements->set(capture_count + 2, *subject);
3431 builder->Add(*isolate->factory()->NewJSArrayWithElements(elements)); 3465 builder->Add(*isolate->factory()->NewJSArrayWithElements(elements));
3432 } 3466 }
3433 // Swap register vectors, so the last successful match is in 3467 // Swap register vectors, so the last successful match is in
3434 // prev_register_vector. 3468 // prev_register_vector.
3435 Vector<int32_t> tmp = prev_register_vector; 3469 Vector<int32_t> tmp = prev_register_vector;
3436 prev_register_vector = register_vector; 3470 prev_register_vector = register_vector;
3437 register_vector = tmp; 3471 register_vector = tmp;
3438 3472
3439 if (match_end > match_start) { 3473 if (match_end > match_start) {
3440 pos = match_end; 3474 pos = match_end;
3441 } else { 3475 } else {
3442 pos = match_end + 1; 3476 pos = match_end + 1;
3443 if (pos > subject_length) { 3477 if (pos > subject_length) {
3444 break; 3478 break;
3445 } 3479 }
3446 } 3480 }
3447 3481
3448 result = RegExpImpl::IrregexpExecOnce(regexp, 3482 result = RegExpImpl::IrregexpExecOnce(regexp,
3449 subject, 3483 subject,
3450 pos, 3484 pos,
3451 register_vector); 3485 register_vector);
3486 first = false;
3452 } while (result == RegExpImpl::RE_SUCCESS); 3487 } while (result == RegExpImpl::RE_SUCCESS);
3453 3488
3454 if (result != RegExpImpl::RE_EXCEPTION) { 3489 if (result != RegExpImpl::RE_EXCEPTION) {
3455 // Finished matching, with at least one match. 3490 // Finished matching, with at least one match.
3456 if (match_end < subject_length) { 3491 if (match_end < subject_length) {
3457 ReplacementStringBuilder::AddSubjectSlice(builder, 3492 ReplacementStringBuilder::AddSubjectSlice(builder,
3458 match_end, 3493 match_end,
3459 subject_length); 3494 subject_length);
3460 } 3495 }
3461 3496
(...skipping 26 matching lines...) Expand all
3488 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 3523 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
3489 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2); 3524 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
3490 CONVERT_ARG_CHECKED(JSArray, result_array, 3); 3525 CONVERT_ARG_CHECKED(JSArray, result_array, 3);
3491 3526
3492 ASSERT(last_match_info->HasFastElements()); 3527 ASSERT(last_match_info->HasFastElements());
3493 ASSERT(regexp->GetFlags().is_global()); 3528 ASSERT(regexp->GetFlags().is_global());
3494 Handle<FixedArray> result_elements; 3529 Handle<FixedArray> result_elements;
3495 if (result_array->HasFastElements()) { 3530 if (result_array->HasFastElements()) {
3496 result_elements = 3531 result_elements =
3497 Handle<FixedArray>(FixedArray::cast(result_array->elements())); 3532 Handle<FixedArray>(FixedArray::cast(result_array->elements()));
3498 } else { 3533 }
3534 if (result_elements.is_null() || result_elements->length() < 16) {
3499 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); 3535 result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
3500 } 3536 }
3501 FixedArrayBuilder builder(result_elements); 3537 FixedArrayBuilder builder(result_elements);
3502 3538
3503 if (regexp->TypeTag() == JSRegExp::ATOM) { 3539 if (regexp->TypeTag() == JSRegExp::ATOM) {
3504 Handle<String> pattern( 3540 Handle<String> pattern(
3505 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex))); 3541 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
3506 ASSERT(pattern->IsFlat()); 3542 ASSERT(pattern->IsFlat());
3507 if (SearchStringMultiple(isolate, subject, pattern, 3543 if (SearchStringMultiple(isolate, subject, pattern,
3508 last_match_info, &builder)) { 3544 last_match_info, &builder)) {
(...skipping 21 matching lines...) Expand all
3530 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array); 3566 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
3531 if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value(); 3567 if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value();
3532 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); 3568 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3533 return Failure::Exception(); 3569 return Failure::Exception();
3534 } 3570 }
3535 3571
3536 3572
3537 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) { 3573 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3538 NoHandleAllocation ha; 3574 NoHandleAllocation ha;
3539 ASSERT(args.length() == 2); 3575 ASSERT(args.length() == 2);
3576 CONVERT_SMI_ARG_CHECKED(radix, 1);
3577 RUNTIME_ASSERT(2 <= radix && radix <= 36);
3540 3578
3541 // Fast case where the result is a one character string. 3579 // Fast case where the result is a one character string.
3542 if (args[0]->IsSmi() && args[1]->IsSmi()) { 3580 if (args[0]->IsSmi()) {
3543 int value = Smi::cast(args[0])->value(); 3581 int value = args.smi_at(0);
3544 int radix = Smi::cast(args[1])->value();
3545 if (value >= 0 && value < radix) { 3582 if (value >= 0 && value < radix) {
3546 RUNTIME_ASSERT(radix <= 36);
3547 // Character array used for conversion. 3583 // Character array used for conversion.
3548 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 3584 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
3549 return isolate->heap()-> 3585 return isolate->heap()->
3550 LookupSingleCharacterStringFromCode(kCharTable[value]); 3586 LookupSingleCharacterStringFromCode(kCharTable[value]);
3551 } 3587 }
3552 } 3588 }
3553 3589
3554 // Slow case. 3590 // Slow case.
3555 CONVERT_DOUBLE_CHECKED(value, args[0]); 3591 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3556 if (isnan(value)) { 3592 if (isnan(value)) {
3557 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3593 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3558 } 3594 }
3559 if (isinf(value)) { 3595 if (isinf(value)) {
3560 if (value < 0) { 3596 if (value < 0) {
3561 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3597 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
3562 } 3598 }
3563 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3599 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3564 } 3600 }
3565 CONVERT_DOUBLE_CHECKED(radix_number, args[1]);
3566 int radix = FastD2I(radix_number);
3567 RUNTIME_ASSERT(2 <= radix && radix <= 36);
3568 char* str = DoubleToRadixCString(value, radix); 3601 char* str = DoubleToRadixCString(value, radix);
3569 MaybeObject* result = 3602 MaybeObject* result =
3570 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3603 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
3571 DeleteArray(str); 3604 DeleteArray(str);
3572 return result; 3605 return result;
3573 } 3606 }
3574 3607
3575 3608
3576 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) { 3609 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
3577 NoHandleAllocation ha; 3610 NoHandleAllocation ha;
3578 ASSERT(args.length() == 2); 3611 ASSERT(args.length() == 2);
3579 3612
3580 CONVERT_DOUBLE_CHECKED(value, args[0]); 3613 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3581 if (isnan(value)) { 3614 if (isnan(value)) {
3582 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3615 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3583 } 3616 }
3584 if (isinf(value)) { 3617 if (isinf(value)) {
3585 if (value < 0) { 3618 if (value < 0) {
3586 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3619 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
3587 } 3620 }
3588 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3621 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3589 } 3622 }
3590 CONVERT_DOUBLE_CHECKED(f_number, args[1]); 3623 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3591 int f = FastD2I(f_number); 3624 int f = FastD2I(f_number);
3592 RUNTIME_ASSERT(f >= 0); 3625 RUNTIME_ASSERT(f >= 0);
3593 char* str = DoubleToFixedCString(value, f); 3626 char* str = DoubleToFixedCString(value, f);
3594 MaybeObject* res = 3627 MaybeObject* res =
3595 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3628 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
3596 DeleteArray(str); 3629 DeleteArray(str);
3597 return res; 3630 return res;
3598 } 3631 }
3599 3632
3600 3633
3601 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) { 3634 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
3602 NoHandleAllocation ha; 3635 NoHandleAllocation ha;
3603 ASSERT(args.length() == 2); 3636 ASSERT(args.length() == 2);
3604 3637
3605 CONVERT_DOUBLE_CHECKED(value, args[0]); 3638 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3606 if (isnan(value)) { 3639 if (isnan(value)) {
3607 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3640 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3608 } 3641 }
3609 if (isinf(value)) { 3642 if (isinf(value)) {
3610 if (value < 0) { 3643 if (value < 0) {
3611 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3644 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
3612 } 3645 }
3613 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3646 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3614 } 3647 }
3615 CONVERT_DOUBLE_CHECKED(f_number, args[1]); 3648 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3616 int f = FastD2I(f_number); 3649 int f = FastD2I(f_number);
3617 RUNTIME_ASSERT(f >= -1 && f <= 20); 3650 RUNTIME_ASSERT(f >= -1 && f <= 20);
3618 char* str = DoubleToExponentialCString(value, f); 3651 char* str = DoubleToExponentialCString(value, f);
3619 MaybeObject* res = 3652 MaybeObject* res =
3620 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3653 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
3621 DeleteArray(str); 3654 DeleteArray(str);
3622 return res; 3655 return res;
3623 } 3656 }
3624 3657
3625 3658
3626 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) { 3659 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
3627 NoHandleAllocation ha; 3660 NoHandleAllocation ha;
3628 ASSERT(args.length() == 2); 3661 ASSERT(args.length() == 2);
3629 3662
3630 CONVERT_DOUBLE_CHECKED(value, args[0]); 3663 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3631 if (isnan(value)) { 3664 if (isnan(value)) {
3632 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); 3665 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3633 } 3666 }
3634 if (isinf(value)) { 3667 if (isinf(value)) {
3635 if (value < 0) { 3668 if (value < 0) {
3636 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); 3669 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity"));
3637 } 3670 }
3638 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); 3671 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3639 } 3672 }
3640 CONVERT_DOUBLE_CHECKED(f_number, args[1]); 3673 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3641 int f = FastD2I(f_number); 3674 int f = FastD2I(f_number);
3642 RUNTIME_ASSERT(f >= 1 && f <= 21); 3675 RUNTIME_ASSERT(f >= 1 && f <= 21);
3643 char* str = DoubleToPrecisionCString(value, f); 3676 char* str = DoubleToPrecisionCString(value, f);
3644 MaybeObject* res = 3677 MaybeObject* res =
3645 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); 3678 isolate->heap()->AllocateStringFromAscii(CStrVector(str));
3646 DeleteArray(str); 3679 DeleteArray(str);
3647 return res; 3680 return res;
3648 } 3681 }
3649 3682
3650 3683
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3720 Execution::ToString(key, &has_pending_exception); 3753 Execution::ToString(key, &has_pending_exception);
3721 if (has_pending_exception) return Failure::Exception(); 3754 if (has_pending_exception) return Failure::Exception();
3722 name = Handle<String>::cast(converted); 3755 name = Handle<String>::cast(converted);
3723 } 3756 }
3724 3757
3725 // Check if the name is trivially convertible to an index and get 3758 // Check if the name is trivially convertible to an index and get
3726 // the element if so. 3759 // the element if so.
3727 if (name->AsArrayIndex(&index)) { 3760 if (name->AsArrayIndex(&index)) {
3728 return GetElementOrCharAt(isolate, object, index); 3761 return GetElementOrCharAt(isolate, object, index);
3729 } else { 3762 } else {
3730 PropertyAttributes attr; 3763 return object->GetProperty(*name);
3731 return object->GetProperty(*name, &attr);
3732 } 3764 }
3733 } 3765 }
3734 3766
3735 3767
3736 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) { 3768 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
3737 NoHandleAllocation ha; 3769 NoHandleAllocation ha;
3738 ASSERT(args.length() == 2); 3770 ASSERT(args.length() == 2);
3739 3771
3740 Handle<Object> object = args.at<Object>(0); 3772 Handle<Object> object = args.at<Object>(0);
3741 Handle<Object> key = args.at<Object>(1); 3773 Handle<Object> key = args.at<Object>(1);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3793 if (!receiver->IsGlobalObject()) return value; 3825 if (!receiver->IsGlobalObject()) return value;
3794 value = JSGlobalPropertyCell::cast(value)->value(); 3826 value = JSGlobalPropertyCell::cast(value)->value();
3795 if (!value->IsTheHole()) return value; 3827 if (!value->IsTheHole()) return value;
3796 // If value is the hole do the general lookup. 3828 // If value is the hole do the general lookup.
3797 } 3829 }
3798 } 3830 }
3799 } else if (args[0]->IsString() && args[1]->IsSmi()) { 3831 } else if (args[0]->IsString() && args[1]->IsSmi()) {
3800 // Fast case for string indexing using [] with a smi index. 3832 // Fast case for string indexing using [] with a smi index.
3801 HandleScope scope(isolate); 3833 HandleScope scope(isolate);
3802 Handle<String> str = args.at<String>(0); 3834 Handle<String> str = args.at<String>(0);
3803 int index = Smi::cast(args[1])->value(); 3835 int index = args.smi_at(1);
3804 if (index >= 0 && index < str->length()) { 3836 if (index >= 0 && index < str->length()) {
3805 Handle<Object> result = GetCharAt(str, index); 3837 Handle<Object> result = GetCharAt(str, index);
3806 return *result; 3838 return *result;
3807 } 3839 }
3808 } 3840 }
3809 3841
3810 // Fall back to GetObjectProperty. 3842 // Fall back to GetObjectProperty.
3811 return Runtime::GetObjectProperty(isolate, 3843 return Runtime::GetObjectProperty(isolate,
3812 args.at<Object>(0), 3844 args.at<Object>(0),
3813 args.at<Object>(1)); 3845 args.at<Object>(1));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3881 // Normalize the elements to enable attributes on the property. 3913 // Normalize the elements to enable attributes on the property.
3882 if (js_object->IsJSGlobalProxy()) { 3914 if (js_object->IsJSGlobalProxy()) {
3883 // We do not need to do access checks here since these has already 3915 // We do not need to do access checks here since these has already
3884 // been performed by the call to GetOwnProperty. 3916 // been performed by the call to GetOwnProperty.
3885 Handle<Object> proto(js_object->GetPrototype()); 3917 Handle<Object> proto(js_object->GetPrototype());
3886 // If proxy is detached, ignore the assignment. Alternatively, 3918 // If proxy is detached, ignore the assignment. Alternatively,
3887 // we could throw an exception. 3919 // we could throw an exception.
3888 if (proto->IsNull()) return *obj_value; 3920 if (proto->IsNull()) return *obj_value;
3889 js_object = Handle<JSObject>::cast(proto); 3921 js_object = Handle<JSObject>::cast(proto);
3890 } 3922 }
3891 NormalizeElements(js_object); 3923 Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
3892 Handle<NumberDictionary> dictionary(js_object->element_dictionary());
3893 // Make sure that we never go back to fast case. 3924 // Make sure that we never go back to fast case.
3894 dictionary->set_requires_slow_elements(); 3925 dictionary->set_requires_slow_elements();
3895 PropertyDetails details = PropertyDetails(attr, NORMAL); 3926 PropertyDetails details = PropertyDetails(attr, NORMAL);
3896 NumberDictionarySet(dictionary, index, obj_value, details); 3927 Handle<NumberDictionary> extended_dictionary =
3928 NumberDictionarySet(dictionary, index, obj_value, details);
3929 if (*extended_dictionary != *dictionary) {
3930 if (js_object->GetElementsKind() ==
3931 JSObject::NON_STRICT_ARGUMENTS_ELEMENTS) {
3932 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary);
3933 } else {
3934 js_object->set_elements(*extended_dictionary);
3935 }
3936 }
3897 return *obj_value; 3937 return *obj_value;
3898 } 3938 }
3899 3939
3900 LookupResult result; 3940 LookupResult result;
3901 js_object->LookupRealNamedProperty(*name, &result); 3941 js_object->LocalLookupRealNamedProperty(*name, &result);
3902 3942
3903 // To be compatible with safari we do not change the value on API objects 3943 // To be compatible with safari we do not change the value on API objects
3904 // in defineProperty. Firefox disagrees here, and actually changes the value. 3944 // in defineProperty. Firefox disagrees here, and actually changes the value.
3905 if (result.IsProperty() && 3945 if (result.IsProperty() &&
3906 (result.type() == CALLBACKS) && 3946 (result.type() == CALLBACKS) &&
3907 result.GetCallbackObject()->IsAccessorInfo()) { 3947 result.GetCallbackObject()->IsAccessorInfo()) {
3908 return isolate->heap()->undefined_value(); 3948 return isolate->heap()->undefined_value();
3909 } 3949 }
3910 3950
3911 // Take special care when attributes are different and there is already 3951 // Take special care when attributes are different and there is already
(...skipping 19 matching lines...) Expand all
3931 } 3971 }
3932 3972
3933 return Runtime::ForceSetObjectProperty(isolate, 3973 return Runtime::ForceSetObjectProperty(isolate,
3934 js_object, 3974 js_object,
3935 name, 3975 name,
3936 obj_value, 3976 obj_value,
3937 attr); 3977 attr);
3938 } 3978 }
3939 3979
3940 3980
3981 // Special case for elements if any of the flags are true.
3982 // If elements are in fast case we always implicitly assume that:
3983 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
3984 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate,
3985 Handle<JSObject> js_object,
3986 uint32_t index,
3987 Handle<Object> value,
3988 PropertyAttributes attr) {
3989 // Normalize the elements to enable attributes on the property.
3990 Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
3991 // Make sure that we never go back to fast case.
3992 dictionary->set_requires_slow_elements();
3993 PropertyDetails details = PropertyDetails(attr, NORMAL);
3994 Handle<NumberDictionary> extended_dictionary =
3995 NumberDictionarySet(dictionary, index, value, details);
3996 if (*extended_dictionary != *dictionary) {
3997 js_object->set_elements(*extended_dictionary);
3998 }
3999 return *value;
4000 }
4001
4002
3941 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, 4003 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3942 Handle<Object> object, 4004 Handle<Object> object,
3943 Handle<Object> key, 4005 Handle<Object> key,
3944 Handle<Object> value, 4006 Handle<Object> value,
3945 PropertyAttributes attr, 4007 PropertyAttributes attr,
3946 StrictModeFlag strict_mode) { 4008 StrictModeFlag strict_mode) {
3947 HandleScope scope(isolate); 4009 HandleScope scope(isolate);
3948 4010
3949 if (object->IsUndefined() || object->IsNull()) { 4011 if (object->IsUndefined() || object->IsNull()) {
3950 Handle<Object> args[2] = { key, object }; 4012 Handle<Object> args[2] = { key, object };
(...skipping 15 matching lines...) Expand all
3966 // of a string using [] notation. We need to support this too in 4028 // of a string using [] notation. We need to support this too in
3967 // JavaScript. 4029 // JavaScript.
3968 // In the case of a String object we just need to redirect the assignment to 4030 // In the case of a String object we just need to redirect the assignment to
3969 // the underlying string if the index is in range. Since the underlying 4031 // the underlying string if the index is in range. Since the underlying
3970 // string does nothing with the assignment then we can ignore such 4032 // string does nothing with the assignment then we can ignore such
3971 // assignments. 4033 // assignments.
3972 if (js_object->IsStringObjectWithCharacterAt(index)) { 4034 if (js_object->IsStringObjectWithCharacterAt(index)) {
3973 return *value; 4035 return *value;
3974 } 4036 }
3975 4037
4038 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4039 return NormalizeObjectSetElement(isolate, js_object, index, value, attr);
4040 }
4041
3976 Handle<Object> result = SetElement(js_object, index, value, strict_mode); 4042 Handle<Object> result = SetElement(js_object, index, value, strict_mode);
3977 if (result.is_null()) return Failure::Exception(); 4043 if (result.is_null()) return Failure::Exception();
3978 return *value; 4044 return *value;
3979 } 4045 }
3980 4046
3981 if (key->IsString()) { 4047 if (key->IsString()) {
3982 Handle<Object> result; 4048 Handle<Object> result;
3983 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 4049 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4050 if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4051 return NormalizeObjectSetElement(isolate,
4052 js_object,
4053 index,
4054 value,
4055 attr);
4056 }
3984 result = SetElement(js_object, index, value, strict_mode); 4057 result = SetElement(js_object, index, value, strict_mode);
3985 } else { 4058 } else {
3986 Handle<String> key_string = Handle<String>::cast(key); 4059 Handle<String> key_string = Handle<String>::cast(key);
3987 key_string->TryFlatten(); 4060 key_string->TryFlatten();
3988 result = SetProperty(js_object, key_string, value, attr, strict_mode); 4061 result = SetProperty(js_object, key_string, value, attr, strict_mode);
3989 } 4062 }
3990 if (result.is_null()) return Failure::Exception(); 4063 if (result.is_null()) return Failure::Exception();
3991 return *value; 4064 return *value;
3992 } 4065 }
3993 4066
3994 // Call-back into JavaScript to convert the key to a string. 4067 // Call-back into JavaScript to convert the key to a string.
3995 bool has_pending_exception = false; 4068 bool has_pending_exception = false;
3996 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4069 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
3997 if (has_pending_exception) return Failure::Exception(); 4070 if (has_pending_exception) return Failure::Exception();
3998 Handle<String> name = Handle<String>::cast(converted); 4071 Handle<String> name = Handle<String>::cast(converted);
3999 4072
4000 if (name->AsArrayIndex(&index)) { 4073 if (name->AsArrayIndex(&index)) {
4001 return js_object->SetElement(index, *value, strict_mode); 4074 return js_object->SetElement(index, *value, strict_mode, true);
4002 } else { 4075 } else {
4003 return js_object->SetProperty(*name, *value, attr, strict_mode); 4076 return js_object->SetProperty(*name, *value, attr, strict_mode);
4004 } 4077 }
4005 } 4078 }
4006 4079
4007 4080
4008 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 4081 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4009 Handle<JSObject> js_object, 4082 Handle<JSObject> js_object,
4010 Handle<Object> key, 4083 Handle<Object> key,
4011 Handle<Object> value, 4084 Handle<Object> value,
4012 PropertyAttributes attr) { 4085 PropertyAttributes attr) {
4013 HandleScope scope(isolate); 4086 HandleScope scope(isolate);
4014 4087
4015 // Check if the given key is an array index. 4088 // Check if the given key is an array index.
4016 uint32_t index; 4089 uint32_t index;
4017 if (key->ToArrayIndex(&index)) { 4090 if (key->ToArrayIndex(&index)) {
4018 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 4091 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
4019 // of a string using [] notation. We need to support this too in 4092 // of a string using [] notation. We need to support this too in
4020 // JavaScript. 4093 // JavaScript.
4021 // In the case of a String object we just need to redirect the assignment to 4094 // In the case of a String object we just need to redirect the assignment to
4022 // the underlying string if the index is in range. Since the underlying 4095 // the underlying string if the index is in range. Since the underlying
4023 // string does nothing with the assignment then we can ignore such 4096 // string does nothing with the assignment then we can ignore such
4024 // assignments. 4097 // assignments.
4025 if (js_object->IsStringObjectWithCharacterAt(index)) { 4098 if (js_object->IsStringObjectWithCharacterAt(index)) {
4026 return *value; 4099 return *value;
4027 } 4100 }
4028 4101
4029 return js_object->SetElement(index, *value, kNonStrictMode); 4102 return js_object->SetElement(index, *value, kNonStrictMode, true);
4030 } 4103 }
4031 4104
4032 if (key->IsString()) { 4105 if (key->IsString()) {
4033 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 4106 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4034 return js_object->SetElement(index, *value, kNonStrictMode); 4107 return js_object->SetElement(index, *value, kNonStrictMode, true);
4035 } else { 4108 } else {
4036 Handle<String> key_string = Handle<String>::cast(key); 4109 Handle<String> key_string = Handle<String>::cast(key);
4037 key_string->TryFlatten(); 4110 key_string->TryFlatten();
4038 return js_object->SetLocalPropertyIgnoreAttributes(*key_string, 4111 return js_object->SetLocalPropertyIgnoreAttributes(*key_string,
4039 *value, 4112 *value,
4040 attr); 4113 attr);
4041 } 4114 }
4042 } 4115 }
4043 4116
4044 // Call-back into JavaScript to convert the key to a string. 4117 // Call-back into JavaScript to convert the key to a string.
4045 bool has_pending_exception = false; 4118 bool has_pending_exception = false;
4046 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4119 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
4047 if (has_pending_exception) return Failure::Exception(); 4120 if (has_pending_exception) return Failure::Exception();
4048 Handle<String> name = Handle<String>::cast(converted); 4121 Handle<String> name = Handle<String>::cast(converted);
4049 4122
4050 if (name->AsArrayIndex(&index)) { 4123 if (name->AsArrayIndex(&index)) {
4051 return js_object->SetElement(index, *value, kNonStrictMode); 4124 return js_object->SetElement(index, *value, kNonStrictMode, true);
4052 } else { 4125 } else {
4053 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); 4126 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
4054 } 4127 }
4055 } 4128 }
4056 4129
4057 4130
4058 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate, 4131 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4059 Handle<JSObject> js_object, 4132 Handle<JSObject> js_object,
4060 Handle<Object> key) { 4133 Handle<Object> key) {
4061 HandleScope scope(isolate); 4134 HandleScope scope(isolate);
(...skipping 30 matching lines...) Expand all
4092 } 4165 }
4093 4166
4094 4167
4095 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { 4168 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4096 NoHandleAllocation ha; 4169 NoHandleAllocation ha;
4097 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); 4170 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
4098 4171
4099 Handle<Object> object = args.at<Object>(0); 4172 Handle<Object> object = args.at<Object>(0);
4100 Handle<Object> key = args.at<Object>(1); 4173 Handle<Object> key = args.at<Object>(1);
4101 Handle<Object> value = args.at<Object>(2); 4174 Handle<Object> value = args.at<Object>(2);
4102 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); 4175 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
4103 RUNTIME_ASSERT( 4176 RUNTIME_ASSERT(
4104 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4177 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4105 // Compute attributes. 4178 // Compute attributes.
4106 PropertyAttributes attributes = 4179 PropertyAttributes attributes =
4107 static_cast<PropertyAttributes>(unchecked_attributes); 4180 static_cast<PropertyAttributes>(unchecked_attributes);
4108 4181
4109 StrictModeFlag strict_mode = kNonStrictMode; 4182 StrictModeFlag strict_mode = kNonStrictMode;
4110 if (args.length() == 5) { 4183 if (args.length() == 5) {
4111 CONVERT_SMI_CHECKED(strict_unchecked, args[4]); 4184 CONVERT_SMI_ARG_CHECKED(strict_unchecked, 4);
4112 RUNTIME_ASSERT(strict_unchecked == kStrictMode || 4185 RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
4113 strict_unchecked == kNonStrictMode); 4186 strict_unchecked == kNonStrictMode);
4114 strict_mode = static_cast<StrictModeFlag>(strict_unchecked); 4187 strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
4115 } 4188 }
4116 4189
4117 return Runtime::SetObjectProperty(isolate, 4190 return Runtime::SetObjectProperty(isolate,
4118 object, 4191 object,
4119 key, 4192 key,
4120 value, 4193 value,
4121 attributes, 4194 attributes,
4122 strict_mode); 4195 strict_mode);
4123 } 4196 }
4124 4197
4125 4198
4126 // Set the ES5 native flag on the function. 4199 // Set the native flag on the function.
4127 // This is used to decide if we should transform null and undefined 4200 // This is used to decide if we should transform null and undefined
4128 // into the global object when doing call and apply. 4201 // into the global object when doing call and apply.
4129 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) { 4202 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
4130 NoHandleAllocation ha; 4203 NoHandleAllocation ha;
4131 RUNTIME_ASSERT(args.length() == 1); 4204 RUNTIME_ASSERT(args.length() == 1);
4132 4205
4133 Handle<Object> object = args.at<Object>(0); 4206 Handle<Object> object = args.at<Object>(0);
4134 4207
4135 if (object->IsJSFunction()) { 4208 if (object->IsJSFunction()) {
4136 JSFunction* func = JSFunction::cast(*object); 4209 JSFunction* func = JSFunction::cast(*object);
4137 func->shared()->set_es5_native(true); 4210 func->shared()->set_native(true);
4138 } 4211 }
4139 return isolate->heap()->undefined_value(); 4212 return isolate->heap()->undefined_value();
4140 } 4213 }
4141 4214
4142 4215
4143 // Set a local property, even if it is READ_ONLY. If the property does not 4216 // Set a local property, even if it is READ_ONLY. If the property does not
4144 // exist, it will be added with attributes NONE. 4217 // exist, it will be added with attributes NONE.
4145 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { 4218 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
4146 NoHandleAllocation ha; 4219 NoHandleAllocation ha;
4147 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); 4220 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
(...skipping 14 matching lines...) Expand all
4162 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); 4235 SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
4163 } 4236 }
4164 4237
4165 4238
4166 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { 4239 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
4167 NoHandleAllocation ha; 4240 NoHandleAllocation ha;
4168 ASSERT(args.length() == 3); 4241 ASSERT(args.length() == 3);
4169 4242
4170 CONVERT_CHECKED(JSObject, object, args[0]); 4243 CONVERT_CHECKED(JSObject, object, args[0]);
4171 CONVERT_CHECKED(String, key, args[1]); 4244 CONVERT_CHECKED(String, key, args[1]);
4172 CONVERT_SMI_CHECKED(strict, args[2]); 4245 CONVERT_SMI_ARG_CHECKED(strict, 2);
4173 return object->DeleteProperty(key, (strict == kStrictMode) 4246 return object->DeleteProperty(key, (strict == kStrictMode)
4174 ? JSObject::STRICT_DELETION 4247 ? JSObject::STRICT_DELETION
4175 : JSObject::NORMAL_DELETION); 4248 : JSObject::NORMAL_DELETION);
4176 } 4249 }
4177 4250
4178 4251
4179 static Object* HasLocalPropertyImplementation(Isolate* isolate, 4252 static Object* HasLocalPropertyImplementation(Isolate* isolate,
4180 Handle<JSObject> object, 4253 Handle<JSObject> object,
4181 Handle<String> key) { 4254 Handle<String> key) {
4182 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); 4255 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
4633 switch (instance_type) { 4706 switch (instance_type) {
4634 case ODDBALL_TYPE: 4707 case ODDBALL_TYPE:
4635 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { 4708 if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
4636 return isolate->heap()->boolean_symbol(); 4709 return isolate->heap()->boolean_symbol();
4637 } 4710 }
4638 if (heap_obj->IsNull()) { 4711 if (heap_obj->IsNull()) {
4639 return isolate->heap()->object_symbol(); 4712 return isolate->heap()->object_symbol();
4640 } 4713 }
4641 ASSERT(heap_obj->IsUndefined()); 4714 ASSERT(heap_obj->IsUndefined());
4642 return isolate->heap()->undefined_symbol(); 4715 return isolate->heap()->undefined_symbol();
4643 case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE: 4716 case JS_FUNCTION_TYPE:
4644 return isolate->heap()->function_symbol(); 4717 return isolate->heap()->function_symbol();
4645 default: 4718 default:
4646 // For any kind of object not handled above, the spec rule for 4719 // For any kind of object not handled above, the spec rule for
4647 // host objects gives that it is okay to return "object" 4720 // host objects gives that it is okay to return "object"
4648 return isolate->heap()->object_symbol(); 4721 return isolate->heap()->object_symbol();
4649 } 4722 }
4650 } 4723 }
4651 4724
4652 4725
4653 static bool AreDigits(const char*s, int from, int to) { 4726 static bool AreDigits(const char*s, int from, int to) {
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
5007 5080
5008 5081
5009 // For a string that is less than 32k characters it should always be 5082 // For a string that is less than 32k characters it should always be
5010 // possible to allocate it in new space. 5083 // possible to allocate it in new space.
5011 static const int kMaxGuaranteedNewSpaceString = 32 * 1024; 5084 static const int kMaxGuaranteedNewSpaceString = 32 * 1024;
5012 5085
5013 5086
5014 // Doing JSON quoting cannot make the string more than this many times larger. 5087 // Doing JSON quoting cannot make the string more than this many times larger.
5015 static const int kJsonQuoteWorstCaseBlowup = 6; 5088 static const int kJsonQuoteWorstCaseBlowup = 6;
5016 5089
5090 static const int kSpaceForQuotesAndComma = 3;
5091 static const int kSpaceForBrackets = 2;
5017 5092
5018 // Covers the entire ASCII range (all other characters are unchanged by JSON 5093 // Covers the entire ASCII range (all other characters are unchanged by JSON
5019 // quoting). 5094 // quoting).
5020 static const byte JsonQuoteLengths[kQuoteTableLength] = { 5095 static const byte JsonQuoteLengths[kQuoteTableLength] = {
5021 6, 6, 6, 6, 6, 6, 6, 6, 5096 6, 6, 6, 6, 6, 6, 6, 6,
5022 2, 2, 2, 6, 2, 2, 6, 6, 5097 2, 2, 2, 6, 2, 2, 6, 6,
5023 6, 6, 6, 6, 6, 6, 6, 6, 5098 6, 6, 6, 6, 6, 6, 6, 6,
5024 6, 6, 6, 6, 6, 6, 6, 6, 5099 6, 6, 6, 6, 6, 6, 6, 6,
5025 1, 1, 2, 1, 1, 1, 1, 1, 5100 1, 1, 2, 1, 1, 1, 1, 1,
5026 1, 1, 1, 1, 1, 1, 1, 1, 5101 1, 1, 1, 1, 1, 1, 1, 1,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
5094 for (int i = 0; i < len; i++) { 5169 for (int i = 0; i < len; i++) {
5095 *write_cursor++ = *replacement++; 5170 *write_cursor++ = *replacement++;
5096 } 5171 }
5097 } 5172 }
5098 } 5173 }
5099 *(write_cursor++) = '"'; 5174 *(write_cursor++) = '"';
5100 return new_string; 5175 return new_string;
5101 } 5176 }
5102 5177
5103 5178
5179 template <typename SinkChar, typename SourceChar>
5180 static inline SinkChar* WriteQuoteJsonString(
5181 Isolate* isolate,
5182 SinkChar* write_cursor,
5183 Vector<const SourceChar> characters) {
5184 // SinkChar is only char if SourceChar is guaranteed to be char.
5185 ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
5186 const SourceChar* read_cursor = characters.start();
5187 const SourceChar* end = read_cursor + characters.length();
5188 *(write_cursor++) = '"';
5189 while (read_cursor < end) {
5190 SourceChar c = *(read_cursor++);
5191 if (sizeof(SourceChar) > 1u &&
5192 static_cast<unsigned>(c) >= kQuoteTableLength) {
5193 *(write_cursor++) = static_cast<SinkChar>(c);
5194 } else {
5195 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5196 const char* replacement = JsonQuotes +
5197 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5198 write_cursor[0] = replacement[0];
5199 if (len > 1) {
5200 write_cursor[1] = replacement[1];
5201 if (len > 2) {
5202 ASSERT(len == 6);
5203 write_cursor[2] = replacement[2];
5204 write_cursor[3] = replacement[3];
5205 write_cursor[4] = replacement[4];
5206 write_cursor[5] = replacement[5];
5207 }
5208 }
5209 write_cursor += len;
5210 }
5211 }
5212 *(write_cursor++) = '"';
5213 return write_cursor;
5214 }
5215
5216
5104 template <typename Char, typename StringType, bool comma> 5217 template <typename Char, typename StringType, bool comma>
5105 static MaybeObject* QuoteJsonString(Isolate* isolate, 5218 static MaybeObject* QuoteJsonString(Isolate* isolate,
5106 Vector<const Char> characters) { 5219 Vector<const Char> characters) {
5107 int length = characters.length(); 5220 int length = characters.length();
5108 isolate->counters()->quote_json_char_count()->Increment(length); 5221 isolate->counters()->quote_json_char_count()->Increment(length);
5109 const int kSpaceForQuotes = 2 + (comma ? 1 :0); 5222 int worst_case_length =
5110 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; 5223 length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
5111 if (worst_case_length > kMaxGuaranteedNewSpaceString) { 5224 if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5112 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters); 5225 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
5113 } 5226 }
5114 5227
5115 MaybeObject* new_alloc = AllocateRawString<StringType>(isolate, 5228 MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
5116 worst_case_length); 5229 worst_case_length);
5117 Object* new_object; 5230 Object* new_object;
5118 if (!new_alloc->ToObject(&new_object)) { 5231 if (!new_alloc->ToObject(&new_object)) {
5119 return new_alloc; 5232 return new_alloc;
5120 } 5233 }
5121 if (!isolate->heap()->new_space()->Contains(new_object)) { 5234 if (!isolate->heap()->new_space()->Contains(new_object)) {
5122 // Even if our string is small enough to fit in new space we still have to 5235 // Even if our string is small enough to fit in new space we still have to
5123 // handle it being allocated in old space as may happen in the third 5236 // handle it being allocated in old space as may happen in the third
5124 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in 5237 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5125 // CEntryStub::GenerateCore. 5238 // CEntryStub::GenerateCore.
5126 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters); 5239 return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
5127 } 5240 }
5128 StringType* new_string = StringType::cast(new_object); 5241 StringType* new_string = StringType::cast(new_object);
5129 ASSERT(isolate->heap()->new_space()->Contains(new_string)); 5242 ASSERT(isolate->heap()->new_space()->Contains(new_string));
5130 5243
5131 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); 5244 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5132 Char* write_cursor = reinterpret_cast<Char*>( 5245 Char* write_cursor = reinterpret_cast<Char*>(
5133 new_string->address() + SeqAsciiString::kHeaderSize); 5246 new_string->address() + SeqAsciiString::kHeaderSize);
5134 if (comma) *(write_cursor++) = ','; 5247 if (comma) *(write_cursor++) = ',';
5135 *(write_cursor++) = '"'; 5248 write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
5136 5249 write_cursor,
5137 const Char* read_cursor = characters.start(); 5250 characters);
5138 const Char* end = read_cursor + length;
5139 while (read_cursor < end) {
5140 Char c = *(read_cursor++);
5141 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
5142 *(write_cursor++) = c;
5143 } else {
5144 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5145 const char* replacement = JsonQuotes +
5146 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5147 write_cursor[0] = replacement[0];
5148 if (len > 1) {
5149 write_cursor[1] = replacement[1];
5150 if (len > 2) {
5151 ASSERT(len == 6);
5152 write_cursor[2] = replacement[2];
5153 write_cursor[3] = replacement[3];
5154 write_cursor[4] = replacement[4];
5155 write_cursor[5] = replacement[5];
5156 }
5157 }
5158 write_cursor += len;
5159 }
5160 }
5161 *(write_cursor++) = '"';
5162
5163 int final_length = static_cast<int>( 5251 int final_length = static_cast<int>(
5164 write_cursor - reinterpret_cast<Char*>( 5252 write_cursor - reinterpret_cast<Char*>(
5165 new_string->address() + SeqAsciiString::kHeaderSize)); 5253 new_string->address() + SeqAsciiString::kHeaderSize));
5166 isolate->heap()->new_space()-> 5254 isolate->heap()->new_space()->
5167 template ShrinkStringAtAllocationBoundary<StringType>( 5255 template ShrinkStringAtAllocationBoundary<StringType>(
5168 new_string, final_length); 5256 new_string, final_length);
5169 return new_string; 5257 return new_string;
5170 } 5258 }
5171 5259
5172 5260
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5206 } 5294 }
5207 if (str->IsTwoByteRepresentation()) { 5295 if (str->IsTwoByteRepresentation()) {
5208 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, 5296 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
5209 str->ToUC16Vector()); 5297 str->ToUC16Vector());
5210 } else { 5298 } else {
5211 return QuoteJsonString<char, SeqAsciiString, true>(isolate, 5299 return QuoteJsonString<char, SeqAsciiString, true>(isolate,
5212 str->ToAsciiVector()); 5300 str->ToAsciiVector());
5213 } 5301 }
5214 } 5302 }
5215 5303
5304
5305 template <typename Char, typename StringType>
5306 static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
5307 FixedArray* array,
5308 int worst_case_length) {
5309 int length = array->length();
5310
5311 MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
5312 worst_case_length);
5313 Object* new_object;
5314 if (!new_alloc->ToObject(&new_object)) {
5315 return new_alloc;
5316 }
5317 if (!isolate->heap()->new_space()->Contains(new_object)) {
5318 // Even if our string is small enough to fit in new space we still have to
5319 // handle it being allocated in old space as may happen in the third
5320 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5321 // CEntryStub::GenerateCore.
5322 return isolate->heap()->undefined_value();
5323 }
5324 AssertNoAllocation no_gc;
5325 StringType* new_string = StringType::cast(new_object);
5326 ASSERT(isolate->heap()->new_space()->Contains(new_string));
5327
5328 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5329 Char* write_cursor = reinterpret_cast<Char*>(
5330 new_string->address() + SeqAsciiString::kHeaderSize);
5331 *(write_cursor++) = '[';
5332 for (int i = 0; i < length; i++) {
5333 if (i != 0) *(write_cursor++) = ',';
5334 String* str = String::cast(array->get(i));
5335 if (str->IsTwoByteRepresentation()) {
5336 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
5337 write_cursor,
5338 str->ToUC16Vector());
5339 } else {
5340 write_cursor = WriteQuoteJsonString<Char, char>(isolate,
5341 write_cursor,
5342 str->ToAsciiVector());
5343 }
5344 }
5345 *(write_cursor++) = ']';
5346
5347 int final_length = static_cast<int>(
5348 write_cursor - reinterpret_cast<Char*>(
5349 new_string->address() + SeqAsciiString::kHeaderSize));
5350 isolate->heap()->new_space()->
5351 template ShrinkStringAtAllocationBoundary<StringType>(
5352 new_string, final_length);
5353 return new_string;
5354 }
5355
5356
5357 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
5358 NoHandleAllocation ha;
5359 ASSERT(args.length() == 1);
5360 CONVERT_CHECKED(JSArray, array, args[0]);
5361
5362 if (!array->HasFastElements()) return isolate->heap()->undefined_value();
5363 FixedArray* elements = FixedArray::cast(array->elements());
5364 int n = elements->length();
5365 bool ascii = true;
5366 int total_length = 0;
5367
5368 for (int i = 0; i < n; i++) {
5369 Object* elt = elements->get(i);
5370 if (!elt->IsString()) return isolate->heap()->undefined_value();
5371 String* element = String::cast(elt);
5372 if (!element->IsFlat()) return isolate->heap()->undefined_value();
5373 total_length += element->length();
5374 if (ascii && element->IsTwoByteRepresentation()) {
5375 ascii = false;
5376 }
5377 }
5378
5379 int worst_case_length =
5380 kSpaceForBrackets + n * kSpaceForQuotesAndComma
5381 + total_length * kJsonQuoteWorstCaseBlowup;
5382
5383 if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5384 return isolate->heap()->undefined_value();
5385 }
5386
5387 if (ascii) {
5388 return QuoteJsonStringArray<char, SeqAsciiString>(isolate,
5389 elements,
5390 worst_case_length);
5391 } else {
5392 return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
5393 elements,
5394 worst_case_length);
5395 }
5396 }
5397
5398
5216 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) { 5399 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
5217 NoHandleAllocation ha; 5400 NoHandleAllocation ha;
5218 5401
5219 CONVERT_CHECKED(String, s, args[0]); 5402 CONVERT_CHECKED(String, s, args[0]);
5220 CONVERT_SMI_CHECKED(radix, args[1]); 5403 CONVERT_SMI_ARG_CHECKED(radix, 1);
5221 5404
5222 s->TryFlatten(); 5405 s->TryFlatten();
5223 5406
5224 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); 5407 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
5225 double value = StringToInt(isolate->unicode_cache(), s, radix); 5408 double value = StringToInt(isolate->unicode_cache(), s, radix);
5226 return isolate->heap()->NumberFromDouble(value); 5409 return isolate->heap()->NumberFromDouble(value);
5227 } 5410 }
5228 5411
5229 5412
5230 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) { 5413 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
5557 int right = length; 5740 int right = length;
5558 if (trimRight) { 5741 if (trimRight) {
5559 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) { 5742 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
5560 right--; 5743 right--;
5561 } 5744 }
5562 } 5745 }
5563 return s->SubString(left, right); 5746 return s->SubString(left, right);
5564 } 5747 }
5565 5748
5566 5749
5750 void FindAsciiStringIndices(Vector<const char> subject,
5751 char pattern,
5752 ZoneList<int>* indices,
5753 unsigned int limit) {
5754 ASSERT(limit > 0);
5755 // Collect indices of pattern in subject using memchr.
5756 // Stop after finding at most limit values.
5757 const char* subject_start = reinterpret_cast<const char*>(subject.start());
5758 const char* subject_end = subject_start + subject.length();
5759 const char* pos = subject_start;
5760 while (limit > 0) {
5761 pos = reinterpret_cast<const char*>(
5762 memchr(pos, pattern, subject_end - pos));
5763 if (pos == NULL) return;
5764 indices->Add(static_cast<int>(pos - subject_start));
5765 pos++;
5766 limit--;
5767 }
5768 }
5769
5770
5567 template <typename SubjectChar, typename PatternChar> 5771 template <typename SubjectChar, typename PatternChar>
5568 void FindStringIndices(Isolate* isolate, 5772 void FindStringIndices(Isolate* isolate,
5569 Vector<const SubjectChar> subject, 5773 Vector<const SubjectChar> subject,
5570 Vector<const PatternChar> pattern, 5774 Vector<const PatternChar> pattern,
5571 ZoneList<int>* indices, 5775 ZoneList<int>* indices,
5572 unsigned int limit) { 5776 unsigned int limit) {
5573 ASSERT(limit > 0); 5777 ASSERT(limit > 0);
5574 // Collect indices of pattern in subject, and the end-of-string index. 5778 // Collect indices of pattern in subject.
5575 // Stop after finding at most limit values. 5779 // Stop after finding at most limit values.
5576 StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5577 int pattern_length = pattern.length(); 5780 int pattern_length = pattern.length();
5578 int index = 0; 5781 int index = 0;
5782 StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5579 while (limit > 0) { 5783 while (limit > 0) {
5580 index = search.Search(subject, index); 5784 index = search.Search(subject, index);
5581 if (index < 0) return; 5785 if (index < 0) return;
5582 indices->Add(index); 5786 indices->Add(index);
5583 index += pattern_length; 5787 index += pattern_length;
5584 limit--; 5788 limit--;
5585 } 5789 }
5586 } 5790 }
5587 5791
5588 5792
(...skipping 22 matching lines...) Expand all
5611 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); 5815 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
5612 ZoneList<int> indices(initial_capacity); 5816 ZoneList<int> indices(initial_capacity);
5613 if (!pattern->IsFlat()) FlattenString(pattern); 5817 if (!pattern->IsFlat()) FlattenString(pattern);
5614 5818
5615 // No allocation block. 5819 // No allocation block.
5616 { 5820 {
5617 AssertNoAllocation nogc; 5821 AssertNoAllocation nogc;
5618 if (subject->IsAsciiRepresentation()) { 5822 if (subject->IsAsciiRepresentation()) {
5619 Vector<const char> subject_vector = subject->ToAsciiVector(); 5823 Vector<const char> subject_vector = subject->ToAsciiVector();
5620 if (pattern->IsAsciiRepresentation()) { 5824 if (pattern->IsAsciiRepresentation()) {
5621 FindStringIndices(isolate, 5825 Vector<const char> pattern_vector = pattern->ToAsciiVector();
5622 subject_vector, 5826 if (pattern_vector.length() == 1) {
5623 pattern->ToAsciiVector(), 5827 FindAsciiStringIndices(subject_vector,
5624 &indices, 5828 pattern_vector[0],
5625 limit); 5829 &indices,
5830 limit);
5831 } else {
5832 FindStringIndices(isolate,
5833 subject_vector,
5834 pattern_vector,
5835 &indices,
5836 limit);
5837 }
5626 } else { 5838 } else {
5627 FindStringIndices(isolate, 5839 FindStringIndices(isolate,
5628 subject_vector, 5840 subject_vector,
5629 pattern->ToUC16Vector(), 5841 pattern->ToUC16Vector(),
5630 &indices, 5842 &indices,
5631 limit); 5843 limit);
5632 } 5844 }
5633 } else { 5845 } else {
5634 Vector<const uc16> subject_vector = subject->ToUC16Vector(); 5846 Vector<const uc16> subject_vector = subject->ToUC16Vector();
5635 if (pattern->IsAsciiRepresentation()) { 5847 if (pattern->IsAsciiRepresentation()) {
(...skipping 30 matching lines...) Expand all
5666 FixedArray::cast(result->elements())->set(0, *subject); 5878 FixedArray::cast(result->elements())->set(0, *subject);
5667 return *result; 5879 return *result;
5668 } 5880 }
5669 5881
5670 Handle<FixedArray> elements(FixedArray::cast(result->elements())); 5882 Handle<FixedArray> elements(FixedArray::cast(result->elements()));
5671 int part_start = 0; 5883 int part_start = 0;
5672 for (int i = 0; i < part_count; i++) { 5884 for (int i = 0; i < part_count; i++) {
5673 HandleScope local_loop_handle; 5885 HandleScope local_loop_handle;
5674 int part_end = indices.at(i); 5886 int part_end = indices.at(i);
5675 Handle<String> substring = 5887 Handle<String> substring =
5676 isolate->factory()->NewSubString(subject, part_start, part_end); 5888 isolate->factory()->NewProperSubString(subject, part_start, part_end);
5677 elements->set(i, *substring); 5889 elements->set(i, *substring);
5678 part_start = part_end + pattern_length; 5890 part_start = part_end + pattern_length;
5679 } 5891 }
5680 5892
5681 return *result; 5893 return *result;
5682 } 5894 }
5683 5895
5684 5896
5685 // Copies ascii characters to the given fixed array looking up 5897 // Copies ascii characters to the given fixed array looking up
5686 // one-char strings in the cache. Gives up on the first char that is 5898 // one-char strings in the cache. Gives up on the first char that is
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
5799 RUNTIME_ASSERT(number->IsNumber()); 6011 RUNTIME_ASSERT(number->IsNumber());
5800 6012
5801 return isolate->heap()->NumberToString(number, false); 6013 return isolate->heap()->NumberToString(number, false);
5802 } 6014 }
5803 6015
5804 6016
5805 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) { 6017 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
5806 NoHandleAllocation ha; 6018 NoHandleAllocation ha;
5807 ASSERT(args.length() == 1); 6019 ASSERT(args.length() == 1);
5808 6020
5809 CONVERT_DOUBLE_CHECKED(number, args[0]); 6021 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5810 6022
5811 // We do not include 0 so that we don't have to treat +0 / -0 cases. 6023 // We do not include 0 so that we don't have to treat +0 / -0 cases.
5812 if (number > 0 && number <= Smi::kMaxValue) { 6024 if (number > 0 && number <= Smi::kMaxValue) {
5813 return Smi::FromInt(static_cast<int>(number)); 6025 return Smi::FromInt(static_cast<int>(number));
5814 } 6026 }
5815 return isolate->heap()->NumberFromDouble(DoubleToInteger(number)); 6027 return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
5816 } 6028 }
5817 6029
5818 6030
5819 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) { 6031 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
5820 NoHandleAllocation ha; 6032 NoHandleAllocation ha;
5821 ASSERT(args.length() == 1); 6033 ASSERT(args.length() == 1);
5822 6034
5823 CONVERT_DOUBLE_CHECKED(number, args[0]); 6035 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5824 6036
5825 // We do not include 0 so that we don't have to treat +0 / -0 cases. 6037 // We do not include 0 so that we don't have to treat +0 / -0 cases.
5826 if (number > 0 && number <= Smi::kMaxValue) { 6038 if (number > 0 && number <= Smi::kMaxValue) {
5827 return Smi::FromInt(static_cast<int>(number)); 6039 return Smi::FromInt(static_cast<int>(number));
5828 } 6040 }
5829 6041
5830 double double_value = DoubleToInteger(number); 6042 double double_value = DoubleToInteger(number);
5831 // Map both -0 and +0 to +0. 6043 // Map both -0 and +0 to +0.
5832 if (double_value == 0) double_value = 0; 6044 if (double_value == 0) double_value = 0;
5833 6045
5834 return isolate->heap()->NumberFromDouble(double_value); 6046 return isolate->heap()->NumberFromDouble(double_value);
5835 } 6047 }
5836 6048
5837 6049
5838 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) { 6050 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
5839 NoHandleAllocation ha; 6051 NoHandleAllocation ha;
5840 ASSERT(args.length() == 1); 6052 ASSERT(args.length() == 1);
5841 6053
5842 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); 6054 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
5843 return isolate->heap()->NumberFromUint32(number); 6055 return isolate->heap()->NumberFromUint32(number);
5844 } 6056 }
5845 6057
5846 6058
5847 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) { 6059 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
5848 NoHandleAllocation ha; 6060 NoHandleAllocation ha;
5849 ASSERT(args.length() == 1); 6061 ASSERT(args.length() == 1);
5850 6062
5851 CONVERT_DOUBLE_CHECKED(number, args[0]); 6063 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5852 6064
5853 // We do not include 0 so that we don't have to treat +0 / -0 cases. 6065 // We do not include 0 so that we don't have to treat +0 / -0 cases.
5854 if (number > 0 && number <= Smi::kMaxValue) { 6066 if (number > 0 && number <= Smi::kMaxValue) {
5855 return Smi::FromInt(static_cast<int>(number)); 6067 return Smi::FromInt(static_cast<int>(number));
5856 } 6068 }
5857 return isolate->heap()->NumberFromInt32(DoubleToInt32(number)); 6069 return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
5858 } 6070 }
5859 6071
5860 6072
5861 // Converts a Number to a Smi, if possible. Returns NaN if the number is not 6073 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
(...skipping 21 matching lines...) Expand all
5883 NoHandleAllocation ha; 6095 NoHandleAllocation ha;
5884 ASSERT(args.length() == 0); 6096 ASSERT(args.length() == 0);
5885 return isolate->heap()->AllocateHeapNumber(0); 6097 return isolate->heap()->AllocateHeapNumber(0);
5886 } 6098 }
5887 6099
5888 6100
5889 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) { 6101 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
5890 NoHandleAllocation ha; 6102 NoHandleAllocation ha;
5891 ASSERT(args.length() == 2); 6103 ASSERT(args.length() == 2);
5892 6104
5893 CONVERT_DOUBLE_CHECKED(x, args[0]); 6105 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5894 CONVERT_DOUBLE_CHECKED(y, args[1]); 6106 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5895 return isolate->heap()->NumberFromDouble(x + y); 6107 return isolate->heap()->NumberFromDouble(x + y);
5896 } 6108 }
5897 6109
5898 6110
5899 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) { 6111 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
5900 NoHandleAllocation ha; 6112 NoHandleAllocation ha;
5901 ASSERT(args.length() == 2); 6113 ASSERT(args.length() == 2);
5902 6114
5903 CONVERT_DOUBLE_CHECKED(x, args[0]); 6115 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5904 CONVERT_DOUBLE_CHECKED(y, args[1]); 6116 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5905 return isolate->heap()->NumberFromDouble(x - y); 6117 return isolate->heap()->NumberFromDouble(x - y);
5906 } 6118 }
5907 6119
5908 6120
5909 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) { 6121 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
5910 NoHandleAllocation ha; 6122 NoHandleAllocation ha;
5911 ASSERT(args.length() == 2); 6123 ASSERT(args.length() == 2);
5912 6124
5913 CONVERT_DOUBLE_CHECKED(x, args[0]); 6125 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5914 CONVERT_DOUBLE_CHECKED(y, args[1]); 6126 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5915 return isolate->heap()->NumberFromDouble(x * y); 6127 return isolate->heap()->NumberFromDouble(x * y);
5916 } 6128 }
5917 6129
5918 6130
5919 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) { 6131 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
5920 NoHandleAllocation ha; 6132 NoHandleAllocation ha;
5921 ASSERT(args.length() == 1); 6133 ASSERT(args.length() == 1);
5922 6134
5923 CONVERT_DOUBLE_CHECKED(x, args[0]); 6135 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5924 return isolate->heap()->NumberFromDouble(-x); 6136 return isolate->heap()->NumberFromDouble(-x);
5925 } 6137 }
5926 6138
5927 6139
5928 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) { 6140 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
5929 NoHandleAllocation ha; 6141 NoHandleAllocation ha;
5930 ASSERT(args.length() == 0); 6142 ASSERT(args.length() == 0);
5931 6143
5932 return isolate->heap()->NumberFromDouble(9876543210.0); 6144 return isolate->heap()->NumberFromDouble(9876543210.0);
5933 } 6145 }
5934 6146
5935 6147
5936 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) { 6148 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
5937 NoHandleAllocation ha; 6149 NoHandleAllocation ha;
5938 ASSERT(args.length() == 2); 6150 ASSERT(args.length() == 2);
5939 6151
5940 CONVERT_DOUBLE_CHECKED(x, args[0]); 6152 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5941 CONVERT_DOUBLE_CHECKED(y, args[1]); 6153 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5942 return isolate->heap()->NumberFromDouble(x / y); 6154 return isolate->heap()->NumberFromDouble(x / y);
5943 } 6155 }
5944 6156
5945 6157
5946 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) { 6158 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
5947 NoHandleAllocation ha; 6159 NoHandleAllocation ha;
5948 ASSERT(args.length() == 2); 6160 ASSERT(args.length() == 2);
5949 6161
5950 CONVERT_DOUBLE_CHECKED(x, args[0]); 6162 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5951 CONVERT_DOUBLE_CHECKED(y, args[1]); 6163 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5952 6164
5953 x = modulo(x, y); 6165 x = modulo(x, y);
5954 // NumberFromDouble may return a Smi instead of a Number object 6166 // NumberFromDouble may return a Smi instead of a Number object
5955 return isolate->heap()->NumberFromDouble(x); 6167 return isolate->heap()->NumberFromDouble(x);
5956 } 6168 }
5957 6169
5958 6170
5959 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) { 6171 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) {
5960 NoHandleAllocation ha; 6172 NoHandleAllocation ha;
5961 ASSERT(args.length() == 2); 6173 ASSERT(args.length() == 2);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6006 6218
6007 6219
6008 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { 6220 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
6009 NoHandleAllocation ha; 6221 NoHandleAllocation ha;
6010 ASSERT(args.length() == 3); 6222 ASSERT(args.length() == 3);
6011 CONVERT_CHECKED(JSArray, array, args[0]); 6223 CONVERT_CHECKED(JSArray, array, args[0]);
6012 if (!args[1]->IsSmi()) { 6224 if (!args[1]->IsSmi()) {
6013 isolate->context()->mark_out_of_memory(); 6225 isolate->context()->mark_out_of_memory();
6014 return Failure::OutOfMemoryException(); 6226 return Failure::OutOfMemoryException();
6015 } 6227 }
6016 int array_length = Smi::cast(args[1])->value(); 6228 int array_length = args.smi_at(1);
6017 CONVERT_CHECKED(String, special, args[2]); 6229 CONVERT_CHECKED(String, special, args[2]);
6018 6230
6019 // This assumption is used by the slice encoding in one or two smis. 6231 // This assumption is used by the slice encoding in one or two smis.
6020 ASSERT(Smi::kMaxValue >= String::kMaxLength); 6232 ASSERT(Smi::kMaxValue >= String::kMaxLength);
6021 6233
6022 int special_length = special->length(); 6234 int special_length = special->length();
6023 if (!array->HasFastElements()) { 6235 if (!array->HasFastElements()) {
6024 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6236 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6025 } 6237 }
6026 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6238 FixedArray* fixed_array = FixedArray::cast(array->elements());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
6119 6331
6120 6332
6121 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) { 6333 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
6122 NoHandleAllocation ha; 6334 NoHandleAllocation ha;
6123 ASSERT(args.length() == 3); 6335 ASSERT(args.length() == 3);
6124 CONVERT_CHECKED(JSArray, array, args[0]); 6336 CONVERT_CHECKED(JSArray, array, args[0]);
6125 if (!args[1]->IsSmi()) { 6337 if (!args[1]->IsSmi()) {
6126 isolate->context()->mark_out_of_memory(); 6338 isolate->context()->mark_out_of_memory();
6127 return Failure::OutOfMemoryException(); 6339 return Failure::OutOfMemoryException();
6128 } 6340 }
6129 int array_length = Smi::cast(args[1])->value(); 6341 int array_length = args.smi_at(1);
6130 CONVERT_CHECKED(String, separator, args[2]); 6342 CONVERT_CHECKED(String, separator, args[2]);
6131 6343
6132 if (!array->HasFastElements()) { 6344 if (!array->HasFastElements()) {
6133 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6345 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6134 } 6346 }
6135 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6347 FixedArray* fixed_array = FixedArray::cast(array->elements());
6136 if (fixed_array->length() < array_length) { 6348 if (fixed_array->length() < array_length) {
6137 array_length = fixed_array->length(); 6349 array_length = fixed_array->length();
6138 } 6350 }
6139 6351
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
6397 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); 6609 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
6398 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); 6610 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
6399 return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); 6611 return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
6400 } 6612 }
6401 6613
6402 6614
6403 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) { 6615 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
6404 NoHandleAllocation ha; 6616 NoHandleAllocation ha;
6405 ASSERT(args.length() == 2); 6617 ASSERT(args.length() == 2);
6406 6618
6407 CONVERT_DOUBLE_CHECKED(x, args[0]); 6619 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6408 CONVERT_DOUBLE_CHECKED(y, args[1]); 6620 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6409 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); 6621 if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
6410 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); 6622 if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
6411 if (x == y) return Smi::FromInt(EQUAL); 6623 if (x == y) return Smi::FromInt(EQUAL);
6412 Object* result; 6624 Object* result;
6413 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { 6625 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
6414 result = Smi::FromInt(EQUAL); 6626 result = Smi::FromInt(EQUAL);
6415 } else { 6627 } else {
6416 result = Smi::FromInt(NOT_EQUAL); 6628 result = Smi::FromInt(NOT_EQUAL);
6417 } 6629 }
6418 return result; 6630 return result;
(...skipping 15 matching lines...) Expand all
6434 STATIC_CHECK(EQUAL == 0); 6646 STATIC_CHECK(EQUAL == 0);
6435 STATIC_CHECK(NOT_EQUAL == 1); 6647 STATIC_CHECK(NOT_EQUAL == 1);
6436 return Smi::FromInt(not_equal); 6648 return Smi::FromInt(not_equal);
6437 } 6649 }
6438 6650
6439 6651
6440 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) { 6652 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
6441 NoHandleAllocation ha; 6653 NoHandleAllocation ha;
6442 ASSERT(args.length() == 3); 6654 ASSERT(args.length() == 3);
6443 6655
6444 CONVERT_DOUBLE_CHECKED(x, args[0]); 6656 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6445 CONVERT_DOUBLE_CHECKED(y, args[1]); 6657 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6446 if (isnan(x) || isnan(y)) return args[2]; 6658 if (isnan(x) || isnan(y)) return args[2];
6447 if (x == y) return Smi::FromInt(EQUAL); 6659 if (x == y) return Smi::FromInt(EQUAL);
6448 if (isless(x, y)) return Smi::FromInt(LESS); 6660 if (isless(x, y)) return Smi::FromInt(LESS);
6449 return Smi::FromInt(GREATER); 6661 return Smi::FromInt(GREATER);
6450 } 6662 }
6451 6663
6452 6664
6453 // Compare two Smis as if they were converted to strings and then 6665 // Compare two Smis as if they were converted to strings and then
6454 // compared lexicographically. 6666 // compared lexicographically.
6455 RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) { 6667 RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
6456 NoHandleAllocation ha; 6668 NoHandleAllocation ha;
6457 ASSERT(args.length() == 2); 6669 ASSERT(args.length() == 2);
6458 6670
6459 // Extract the integer values from the Smis. 6671 // Extract the integer values from the Smis.
6460 CONVERT_CHECKED(Smi, x, args[0]); 6672 CONVERT_CHECKED(Smi, x, args[0]);
6461 CONVERT_CHECKED(Smi, y, args[1]); 6673 CONVERT_CHECKED(Smi, y, args[1]);
6462 int x_value = x->value(); 6674 int x_value = x->value();
6463 int y_value = y->value(); 6675 int y_value = y->value();
6464 6676
6465 // If the integers are equal so are the string representations. 6677 // If the integers are equal so are the string representations.
6466 if (x_value == y_value) return Smi::FromInt(EQUAL); 6678 if (x_value == y_value) return Smi::FromInt(EQUAL);
6467 6679
6468 // If one of the integers are zero the normal integer order is the 6680 // If one of the integers is zero the normal integer order is the
6469 // same as the lexicographic order of the string representations. 6681 // same as the lexicographic order of the string representations.
6470 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); 6682 if (x_value == 0 || y_value == 0)
6683 return Smi::FromInt(x_value < y_value ? LESS : GREATER);
6471 6684
6472 // If only one of the integers is negative the negative number is 6685 // If only one of the integers is negative the negative number is
6473 // smallest because the char code of '-' is less than the char code 6686 // smallest because the char code of '-' is less than the char code
6474 // of any digit. Otherwise, we make both values positive. 6687 // of any digit. Otherwise, we make both values positive.
6688
6689 // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
6690 // architectures using 32-bit Smis.
6691 uint32_t x_scaled = x_value;
6692 uint32_t y_scaled = y_value;
6475 if (x_value < 0 || y_value < 0) { 6693 if (x_value < 0 || y_value < 0) {
6476 if (y_value >= 0) return Smi::FromInt(LESS); 6694 if (y_value >= 0) return Smi::FromInt(LESS);
6477 if (x_value >= 0) return Smi::FromInt(GREATER); 6695 if (x_value >= 0) return Smi::FromInt(GREATER);
6478 x_value = -x_value; 6696 x_scaled = -x_value;
6479 y_value = -y_value; 6697 y_scaled = -y_value;
6480 } 6698 }
6481 6699
6482 // Arrays for the individual characters of the two Smis. Smis are 6700 static const uint32_t kPowersOf10[] = {
6483 // 31 bit integers and 10 decimal digits are therefore enough. 6701 1, 10, 100, 1000, 10*1000, 100*1000,
6484 // TODO(isolates): maybe we should simply allocate 20 bytes on the stack. 6702 1000*1000, 10*1000*1000, 100*1000*1000,
6485 int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms(); 6703 1000*1000*1000
6486 int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms(); 6704 };
6487 6705
6706 // If the integers have the same number of decimal digits they can be
6707 // compared directly as the numeric order is the same as the
6708 // lexicographic order. If one integer has fewer digits, it is scaled
6709 // by some power of 10 to have the same number of digits as the longer
6710 // integer. If the scaled integers are equal it means the shorter
6711 // integer comes first in the lexicographic order.
6488 6712
6489 // Convert the integers to arrays of their decimal digits. 6713 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6490 int x_index = 0; 6714 int x_log2 = IntegerLog2(x_scaled);
6491 int y_index = 0; 6715 int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6492 while (x_value > 0) { 6716 x_log10 -= x_scaled < kPowersOf10[x_log10];
6493 x_elms[x_index++] = x_value % 10; 6717
6494 x_value /= 10; 6718 int y_log2 = IntegerLog2(y_scaled);
6495 } 6719 int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6496 while (y_value > 0) { 6720 y_log10 -= y_scaled < kPowersOf10[y_log10];
6497 y_elms[y_index++] = y_value % 10; 6721
6498 y_value /= 10; 6722 int tie = EQUAL;
6723
6724 if (x_log10 < y_log10) {
6725 // X has fewer digits. We would like to simply scale up X but that
6726 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6727 // be scaled up to 9_000_000_000. So we scale up by the next
6728 // smallest power and scale down Y to drop one digit. It is OK to
6729 // drop one digit from the longer integer since the final digit is
6730 // past the length of the shorter integer.
6731 x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
6732 y_scaled /= 10;
6733 tie = LESS;
6734 } else if (y_log10 < x_log10) {
6735 y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
6736 x_scaled /= 10;
6737 tie = GREATER;
6499 } 6738 }
6500 6739
6501 // Loop through the arrays of decimal digits finding the first place 6740 if (x_scaled < y_scaled) return Smi::FromInt(LESS);
6502 // where they differ. 6741 if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
6503 while (--x_index >= 0 && --y_index >= 0) { 6742 return Smi::FromInt(tie);
6504 int diff = x_elms[x_index] - y_elms[y_index];
6505 if (diff != 0) return Smi::FromInt(diff);
6506 }
6507
6508 // If one array is a suffix of the other array, the longest array is
6509 // the representation of the largest of the Smis in the
6510 // lexicographic ordering.
6511 return Smi::FromInt(x_index - y_index);
6512 } 6743 }
6513 6744
6514 6745
6515 static Object* StringInputBufferCompare(RuntimeState* state, 6746 static Object* StringInputBufferCompare(RuntimeState* state,
6516 String* x, 6747 String* x,
6517 String* y) { 6748 String* y) {
6518 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); 6749 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx();
6519 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); 6750 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy();
6520 bufx.Reset(x); 6751 bufx.Reset(x);
6521 bufy.Reset(y); 6752 bufy.Reset(y);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
6608 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) 6839 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
6609 : StringInputBufferCompare(isolate->runtime_state(), x, y); 6840 : StringInputBufferCompare(isolate->runtime_state(), x, y);
6610 } 6841 }
6611 6842
6612 6843
6613 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) { 6844 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
6614 NoHandleAllocation ha; 6845 NoHandleAllocation ha;
6615 ASSERT(args.length() == 1); 6846 ASSERT(args.length() == 1);
6616 isolate->counters()->math_acos()->Increment(); 6847 isolate->counters()->math_acos()->Increment();
6617 6848
6618 CONVERT_DOUBLE_CHECKED(x, args[0]); 6849 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6619 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x); 6850 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
6620 } 6851 }
6621 6852
6622 6853
6623 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) { 6854 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
6624 NoHandleAllocation ha; 6855 NoHandleAllocation ha;
6625 ASSERT(args.length() == 1); 6856 ASSERT(args.length() == 1);
6626 isolate->counters()->math_asin()->Increment(); 6857 isolate->counters()->math_asin()->Increment();
6627 6858
6628 CONVERT_DOUBLE_CHECKED(x, args[0]); 6859 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6629 return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x); 6860 return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
6630 } 6861 }
6631 6862
6632 6863
6633 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) { 6864 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
6634 NoHandleAllocation ha; 6865 NoHandleAllocation ha;
6635 ASSERT(args.length() == 1); 6866 ASSERT(args.length() == 1);
6636 isolate->counters()->math_atan()->Increment(); 6867 isolate->counters()->math_atan()->Increment();
6637 6868
6638 CONVERT_DOUBLE_CHECKED(x, args[0]); 6869 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6639 return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x); 6870 return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
6640 } 6871 }
6641 6872
6642 6873
6643 static const double kPiDividedBy4 = 0.78539816339744830962; 6874 static const double kPiDividedBy4 = 0.78539816339744830962;
6644 6875
6645 6876
6646 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) { 6877 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
6647 NoHandleAllocation ha; 6878 NoHandleAllocation ha;
6648 ASSERT(args.length() == 2); 6879 ASSERT(args.length() == 2);
6649 isolate->counters()->math_atan2()->Increment(); 6880 isolate->counters()->math_atan2()->Increment();
6650 6881
6651 CONVERT_DOUBLE_CHECKED(x, args[0]); 6882 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6652 CONVERT_DOUBLE_CHECKED(y, args[1]); 6883 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6653 double result; 6884 double result;
6654 if (isinf(x) && isinf(y)) { 6885 if (isinf(x) && isinf(y)) {
6655 // Make sure that the result in case of two infinite arguments 6886 // Make sure that the result in case of two infinite arguments
6656 // is a multiple of Pi / 4. The sign of the result is determined 6887 // is a multiple of Pi / 4. The sign of the result is determined
6657 // by the first argument (x) and the sign of the second argument 6888 // by the first argument (x) and the sign of the second argument
6658 // determines the multiplier: one or three. 6889 // determines the multiplier: one or three.
6659 int multiplier = (x < 0) ? -1 : 1; 6890 int multiplier = (x < 0) ? -1 : 1;
6660 if (y < 0) multiplier *= 3; 6891 if (y < 0) multiplier *= 3;
6661 result = multiplier * kPiDividedBy4; 6892 result = multiplier * kPiDividedBy4;
6662 } else { 6893 } else {
6663 result = atan2(x, y); 6894 result = atan2(x, y);
6664 } 6895 }
6665 return isolate->heap()->AllocateHeapNumber(result); 6896 return isolate->heap()->AllocateHeapNumber(result);
6666 } 6897 }
6667 6898
6668 6899
6669 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) { 6900 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
6670 NoHandleAllocation ha; 6901 NoHandleAllocation ha;
6671 ASSERT(args.length() == 1); 6902 ASSERT(args.length() == 1);
6672 isolate->counters()->math_ceil()->Increment(); 6903 isolate->counters()->math_ceil()->Increment();
6673 6904
6674 CONVERT_DOUBLE_CHECKED(x, args[0]); 6905 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6675 return isolate->heap()->NumberFromDouble(ceiling(x)); 6906 return isolate->heap()->NumberFromDouble(ceiling(x));
6676 } 6907 }
6677 6908
6678 6909
6679 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) { 6910 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
6680 NoHandleAllocation ha; 6911 NoHandleAllocation ha;
6681 ASSERT(args.length() == 1); 6912 ASSERT(args.length() == 1);
6682 isolate->counters()->math_cos()->Increment(); 6913 isolate->counters()->math_cos()->Increment();
6683 6914
6684 CONVERT_DOUBLE_CHECKED(x, args[0]); 6915 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6685 return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x); 6916 return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
6686 } 6917 }
6687 6918
6688 6919
6689 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) { 6920 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
6690 NoHandleAllocation ha; 6921 NoHandleAllocation ha;
6691 ASSERT(args.length() == 1); 6922 ASSERT(args.length() == 1);
6692 isolate->counters()->math_exp()->Increment(); 6923 isolate->counters()->math_exp()->Increment();
6693 6924
6694 CONVERT_DOUBLE_CHECKED(x, args[0]); 6925 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6695 return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x); 6926 return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x);
6696 } 6927 }
6697 6928
6698 6929
6699 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) { 6930 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
6700 NoHandleAllocation ha; 6931 NoHandleAllocation ha;
6701 ASSERT(args.length() == 1); 6932 ASSERT(args.length() == 1);
6702 isolate->counters()->math_floor()->Increment(); 6933 isolate->counters()->math_floor()->Increment();
6703 6934
6704 CONVERT_DOUBLE_CHECKED(x, args[0]); 6935 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6705 return isolate->heap()->NumberFromDouble(floor(x)); 6936 return isolate->heap()->NumberFromDouble(floor(x));
6706 } 6937 }
6707 6938
6708 6939
6709 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) { 6940 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
6710 NoHandleAllocation ha; 6941 NoHandleAllocation ha;
6711 ASSERT(args.length() == 1); 6942 ASSERT(args.length() == 1);
6712 isolate->counters()->math_log()->Increment(); 6943 isolate->counters()->math_log()->Increment();
6713 6944
6714 CONVERT_DOUBLE_CHECKED(x, args[0]); 6945 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6715 return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x); 6946 return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
6716 } 6947 }
6717 6948
6718 6949
6719 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) { 6950 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
6720 NoHandleAllocation ha; 6951 NoHandleAllocation ha;
6721 ASSERT(args.length() == 2); 6952 ASSERT(args.length() == 2);
6722 isolate->counters()->math_pow()->Increment(); 6953 isolate->counters()->math_pow()->Increment();
6723 6954
6724 CONVERT_DOUBLE_CHECKED(x, args[0]); 6955 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6725 6956
6726 // If the second argument is a smi, it is much faster to call the 6957 // If the second argument is a smi, it is much faster to call the
6727 // custom powi() function than the generic pow(). 6958 // custom powi() function than the generic pow().
6728 if (args[1]->IsSmi()) { 6959 if (args[1]->IsSmi()) {
6729 int y = Smi::cast(args[1])->value(); 6960 int y = args.smi_at(1);
6730 return isolate->heap()->NumberFromDouble(power_double_int(x, y)); 6961 return isolate->heap()->NumberFromDouble(power_double_int(x, y));
6731 } 6962 }
6732 6963
6733 CONVERT_DOUBLE_CHECKED(y, args[1]); 6964 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6734 return isolate->heap()->AllocateHeapNumber(power_double_double(x, y)); 6965 return isolate->heap()->AllocateHeapNumber(power_double_double(x, y));
6735 } 6966 }
6736 6967
6737 // Fast version of Math.pow if we know that y is not an integer and 6968 // Fast version of Math.pow if we know that y is not an integer and
6738 // y is not -0.5 or 0.5. Used as slowcase from codegen. 6969 // y is not -0.5 or 0.5. Used as slowcase from codegen.
6739 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) { 6970 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
6740 NoHandleAllocation ha; 6971 NoHandleAllocation ha;
6741 ASSERT(args.length() == 2); 6972 ASSERT(args.length() == 2);
6742 CONVERT_DOUBLE_CHECKED(x, args[0]); 6973 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6743 CONVERT_DOUBLE_CHECKED(y, args[1]); 6974 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6744 if (y == 0) { 6975 if (y == 0) {
6745 return Smi::FromInt(1); 6976 return Smi::FromInt(1);
6746 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { 6977 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
6747 return isolate->heap()->nan_value(); 6978 return isolate->heap()->nan_value();
6748 } else { 6979 } else {
6749 return isolate->heap()->AllocateHeapNumber(pow(x, y)); 6980 return isolate->heap()->AllocateHeapNumber(pow(x, y));
6750 } 6981 }
6751 } 6982 }
6752 6983
6753 6984
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6792 // Do not call NumberFromDouble() to avoid extra checks. 7023 // Do not call NumberFromDouble() to avoid extra checks.
6793 return isolate->heap()->AllocateHeapNumber(floor(value + 0.5)); 7024 return isolate->heap()->AllocateHeapNumber(floor(value + 0.5));
6794 } 7025 }
6795 7026
6796 7027
6797 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) { 7028 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
6798 NoHandleAllocation ha; 7029 NoHandleAllocation ha;
6799 ASSERT(args.length() == 1); 7030 ASSERT(args.length() == 1);
6800 isolate->counters()->math_sin()->Increment(); 7031 isolate->counters()->math_sin()->Increment();
6801 7032
6802 CONVERT_DOUBLE_CHECKED(x, args[0]); 7033 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6803 return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x); 7034 return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
6804 } 7035 }
6805 7036
6806 7037
6807 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) { 7038 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
6808 NoHandleAllocation ha; 7039 NoHandleAllocation ha;
6809 ASSERT(args.length() == 1); 7040 ASSERT(args.length() == 1);
6810 isolate->counters()->math_sqrt()->Increment(); 7041 isolate->counters()->math_sqrt()->Increment();
6811 7042
6812 CONVERT_DOUBLE_CHECKED(x, args[0]); 7043 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6813 return isolate->heap()->AllocateHeapNumber(sqrt(x)); 7044 return isolate->heap()->AllocateHeapNumber(sqrt(x));
6814 } 7045 }
6815 7046
6816 7047
6817 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { 7048 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
6818 NoHandleAllocation ha; 7049 NoHandleAllocation ha;
6819 ASSERT(args.length() == 1); 7050 ASSERT(args.length() == 1);
6820 isolate->counters()->math_tan()->Increment(); 7051 isolate->counters()->math_tan()->Increment();
6821 7052
6822 CONVERT_DOUBLE_CHECKED(x, args[0]); 7053 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6823 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); 7054 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
6824 } 7055 }
6825 7056
6826 7057
6827 static int MakeDay(int year, int month, int day) { 7058 static int MakeDay(int year, int month, int day) {
6828 static const int day_from_month[] = {0, 31, 59, 90, 120, 151, 7059 static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
6829 181, 212, 243, 273, 304, 334}; 7060 181, 212, 243, 273, 304, 334};
6830 static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152, 7061 static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
6831 182, 213, 244, 274, 305, 335}; 7062 182, 213, 244, 274, 305, 335};
6832 7063
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6866 } 7097 }
6867 7098
6868 return day_from_year + day_from_month_leap[month] + day - 1; 7099 return day_from_year + day_from_month_leap[month] + day - 1;
6869 } 7100 }
6870 7101
6871 7102
6872 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { 7103 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
6873 NoHandleAllocation ha; 7104 NoHandleAllocation ha;
6874 ASSERT(args.length() == 3); 7105 ASSERT(args.length() == 3);
6875 7106
6876 CONVERT_SMI_CHECKED(year, args[0]); 7107 CONVERT_SMI_ARG_CHECKED(year, 0);
6877 CONVERT_SMI_CHECKED(month, args[1]); 7108 CONVERT_SMI_ARG_CHECKED(month, 1);
6878 CONVERT_SMI_CHECKED(date, args[2]); 7109 CONVERT_SMI_ARG_CHECKED(date, 2);
6879 7110
6880 return Smi::FromInt(MakeDay(year, month, date)); 7111 return Smi::FromInt(MakeDay(year, month, date));
6881 } 7112 }
6882 7113
6883 7114
6884 static const int kDays4Years[] = {0, 365, 2 * 365, 3 * 365 + 1}; 7115 static const int kDays4Years[] = {0, 365, 2 * 365, 3 * 365 + 1};
6885 static const int kDaysIn4Years = 4 * 365 + 1; 7116 static const int kDaysIn4Years = 4 * 365 + 1;
6886 static const int kDaysIn100Years = 25 * kDaysIn4Years - 1; 7117 static const int kDaysIn100Years = 25 * kDaysIn4Years - 1;
6887 static const int kDaysIn400Years = 4 * kDaysIn100Years + 1; 7118 static const int kDaysIn400Years = 4 * kDaysIn100Years + 1;
6888 static const int kDays1970to2000 = 30 * 365 + 7; 7119 static const int kDays1970to2000 = 30 * 365 + 7;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
7165 } else { 7396 } else {
7166 DateYMDFromTimeSlow(date, year, month, day); 7397 DateYMDFromTimeSlow(date, year, month, day);
7167 } 7398 }
7168 } 7399 }
7169 7400
7170 7401
7171 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) { 7402 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7172 NoHandleAllocation ha; 7403 NoHandleAllocation ha;
7173 ASSERT(args.length() == 2); 7404 ASSERT(args.length() == 2);
7174 7405
7175 CONVERT_DOUBLE_CHECKED(t, args[0]); 7406 CONVERT_DOUBLE_ARG_CHECKED(t, 0);
7176 CONVERT_CHECKED(JSArray, res_array, args[1]); 7407 CONVERT_CHECKED(JSArray, res_array, args[1]);
7177 7408
7178 int year, month, day; 7409 int year, month, day;
7179 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); 7410 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
7180 7411
7181 RUNTIME_ASSERT(res_array->elements()->map() == 7412 RUNTIME_ASSERT(res_array->elements()->map() ==
7182 isolate->heap()->fixed_array_map()); 7413 isolate->heap()->fixed_array_map());
7183 FixedArray* elms = FixedArray::cast(res_array->elements()); 7414 FixedArray* elms = FixedArray::cast(res_array->elements());
7184 RUNTIME_ASSERT(elms->length() == 3); 7415 RUNTIME_ASSERT(elms->length() == 3);
7185 7416
7186 elms->set(0, Smi::FromInt(year)); 7417 elms->set(0, Smi::FromInt(year));
7187 elms->set(1, Smi::FromInt(month)); 7418 elms->set(1, Smi::FromInt(month));
7188 elms->set(2, Smi::FromInt(day)); 7419 elms->set(2, Smi::FromInt(day));
7189 7420
7190 return isolate->heap()->undefined_value(); 7421 return isolate->heap()->undefined_value();
7191 } 7422 }
7192 7423
7193 7424
7194 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { 7425 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
7426 HandleScope scope(isolate);
7427 ASSERT(args.length() == 3);
7428
7429 Handle<JSFunction> callee = args.at<JSFunction>(0);
7430 Object** parameters = reinterpret_cast<Object**>(args[1]);
7431 const int argument_count = Smi::cast(args[2])->value();
7432
7433 Handle<JSObject> result =
7434 isolate->factory()->NewArgumentsObject(callee, argument_count);
7435 // Allocate the elements if needed.
7436 int parameter_count = callee->shared()->formal_parameter_count();
7437 if (argument_count > 0) {
7438 if (parameter_count > 0) {
7439 int mapped_count = Min(argument_count, parameter_count);
7440 Handle<FixedArray> parameter_map =
7441 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
7442 parameter_map->set_map(
7443 isolate->heap()->non_strict_arguments_elements_map());
7444
7445 Handle<Map> old_map(result->map());
7446 Handle<Map> new_map =
7447 isolate->factory()->CopyMapDropTransitions(old_map);
7448 new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
7449
7450 result->set_map(*new_map);
7451 result->set_elements(*parameter_map);
7452
7453 // Store the context and the arguments array at the beginning of the
7454 // parameter map.
7455 Handle<Context> context(isolate->context());
7456 Handle<FixedArray> arguments =
7457 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7458 parameter_map->set(0, *context);
7459 parameter_map->set(1, *arguments);
7460
7461 // Loop over the actual parameters backwards.
7462 int index = argument_count - 1;
7463 while (index >= mapped_count) {
7464 // These go directly in the arguments array and have no
7465 // corresponding slot in the parameter map.
7466 arguments->set(index, *(parameters - index - 1));
7467 --index;
7468 }
7469
7470 ScopeInfo<> scope_info(callee->shared()->scope_info());
7471 while (index >= 0) {
7472 // Detect duplicate names to the right in the parameter list.
7473 Handle<String> name = scope_info.parameter_name(index);
7474 int context_slot_count = scope_info.number_of_context_slots();
7475 bool duplicate = false;
7476 for (int j = index + 1; j < parameter_count; ++j) {
7477 if (scope_info.parameter_name(j).is_identical_to(name)) {
7478 duplicate = true;
7479 break;
7480 }
7481 }
7482
7483 if (duplicate) {
7484 // This goes directly in the arguments array with a hole in the
7485 // parameter map.
7486 arguments->set(index, *(parameters - index - 1));
7487 parameter_map->set_the_hole(index + 2);
7488 } else {
7489 // The context index goes in the parameter map with a hole in the
7490 // arguments array.
7491 int context_index = -1;
7492 for (int j = Context::MIN_CONTEXT_SLOTS;
7493 j < context_slot_count;
7494 ++j) {
7495 if (scope_info.context_slot_name(j).is_identical_to(name)) {
7496 context_index = j;
7497 break;
7498 }
7499 }
7500 ASSERT(context_index >= 0);
7501 arguments->set_the_hole(index);
7502 parameter_map->set(index + 2, Smi::FromInt(context_index));
7503 }
7504
7505 --index;
7506 }
7507 } else {
7508 // If there is no aliasing, the arguments object elements are not
7509 // special in any way.
7510 Handle<FixedArray> elements =
7511 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7512 result->set_elements(*elements);
7513 for (int i = 0; i < argument_count; ++i) {
7514 elements->set(i, *(parameters - i - 1));
7515 }
7516 }
7517 }
7518 return *result;
7519 }
7520
7521
7522 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
7195 NoHandleAllocation ha; 7523 NoHandleAllocation ha;
7196 ASSERT(args.length() == 3); 7524 ASSERT(args.length() == 3);
7197 7525
7198 JSFunction* callee = JSFunction::cast(args[0]); 7526 JSFunction* callee = JSFunction::cast(args[0]);
7199 Object** parameters = reinterpret_cast<Object**>(args[1]); 7527 Object** parameters = reinterpret_cast<Object**>(args[1]);
7200 const int length = Smi::cast(args[2])->value(); 7528 const int length = args.smi_at(2);
7201 7529
7202 Object* result; 7530 Object* result;
7203 { MaybeObject* maybe_result = 7531 { MaybeObject* maybe_result =
7204 isolate->heap()->AllocateArgumentsObject(callee, length); 7532 isolate->heap()->AllocateArgumentsObject(callee, length);
7205 if (!maybe_result->ToObject(&result)) return maybe_result; 7533 if (!maybe_result->ToObject(&result)) return maybe_result;
7206 } 7534 }
7207 // Allocate the elements if needed. 7535 // Allocate the elements if needed.
7208 if (length > 0) { 7536 if (length > 0) {
7209 // Allocate the fixed array. 7537 // Allocate the fixed array.
7210 Object* obj; 7538 Object* obj;
(...skipping 16 matching lines...) Expand all
7227 } 7555 }
7228 7556
7229 7557
7230 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) { 7558 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
7231 HandleScope scope(isolate); 7559 HandleScope scope(isolate);
7232 ASSERT(args.length() == 3); 7560 ASSERT(args.length() == 3);
7233 CONVERT_ARG_CHECKED(Context, context, 0); 7561 CONVERT_ARG_CHECKED(Context, context, 0);
7234 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); 7562 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
7235 CONVERT_BOOLEAN_CHECKED(pretenure, args[2]); 7563 CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
7236 7564
7237 // Allocate global closures in old space and allocate local closures 7565 // The caller ensures that we pretenure closures that are assigned
7238 // in new space. Additionally pretenure closures that are assigned
7239 // directly to properties. 7566 // directly to properties.
7240 pretenure = pretenure || (context->global_context() == *context);
7241 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; 7567 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
7242 Handle<JSFunction> result = 7568 Handle<JSFunction> result =
7243 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, 7569 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
7244 context, 7570 context,
7245 pretenure_flag); 7571 pretenure_flag);
7246 return *result; 7572 return *result;
7247 } 7573 }
7248 7574
7249 7575
7250 static SmartPointer<Object**> GetNonBoundArguments(int bound_argc, 7576 static SmartPointer<Object**> GetNonBoundArguments(int bound_argc,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
7350 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); 7676 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
7351 Handle<Object> type_error = 7677 Handle<Object> type_error =
7352 isolate->factory()->NewTypeError("not_constructor", arguments); 7678 isolate->factory()->NewTypeError("not_constructor", arguments);
7353 return isolate->Throw(*type_error); 7679 return isolate->Throw(*type_error);
7354 } 7680 }
7355 7681
7356 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); 7682 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
7357 7683
7358 // If function should not have prototype, construction is not allowed. In this 7684 // If function should not have prototype, construction is not allowed. In this
7359 // case generated code bailouts here, since function has no initial_map. 7685 // case generated code bailouts here, since function has no initial_map.
7360 if (!function->should_have_prototype()) { 7686 if (!function->should_have_prototype() && !function->shared()->bound()) {
7361 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); 7687 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
7362 Handle<Object> type_error = 7688 Handle<Object> type_error =
7363 isolate->factory()->NewTypeError("not_constructor", arguments); 7689 isolate->factory()->NewTypeError("not_constructor", arguments);
7364 return isolate->Throw(*type_error); 7690 return isolate->Throw(*type_error);
7365 } 7691 }
7366 7692
7367 #ifdef ENABLE_DEBUGGER_SUPPORT 7693 #ifdef ENABLE_DEBUGGER_SUPPORT
7368 Debug* debug = isolate->debug(); 7694 Debug* debug = isolate->debug();
7369 // Handle stepping into constructors if step into is active. 7695 // Handle stepping into constructors if step into is active.
7370 if (debug->StepInActive()) { 7696 if (debug->StepInActive()) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
7491 function->ReplaceCode(function->shared()->code()); 7817 function->ReplaceCode(function->shared()->code());
7492 return function->code(); 7818 return function->code();
7493 } 7819 }
7494 7820
7495 7821
7496 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { 7822 RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
7497 HandleScope scope(isolate); 7823 HandleScope scope(isolate);
7498 ASSERT(args.length() == 1); 7824 ASSERT(args.length() == 1);
7499 RUNTIME_ASSERT(args[0]->IsSmi()); 7825 RUNTIME_ASSERT(args[0]->IsSmi());
7500 Deoptimizer::BailoutType type = 7826 Deoptimizer::BailoutType type =
7501 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value()); 7827 static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
7502 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); 7828 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
7503 ASSERT(isolate->heap()->IsAllocationAllowed()); 7829 ASSERT(isolate->heap()->IsAllocationAllowed());
7504 int frames = deoptimizer->output_count(); 7830 int frames = deoptimizer->output_count();
7505 7831
7506 deoptimizer->MaterializeHeapNumbers(); 7832 deoptimizer->MaterializeHeapNumbers();
7507 delete deoptimizer; 7833 delete deoptimizer;
7508 7834
7509 JavaScriptFrameIterator it(isolate); 7835 JavaScriptFrameIterator it(isolate);
7510 JavaScriptFrame* frame = NULL; 7836 JavaScriptFrame* frame = NULL;
7511 for (int i = 0; i < frames - 1; i++) it.Advance(); 7837 for (int i = 0; i < frames - 1; i++) it.Advance();
(...skipping 10 matching lines...) Expand all
7522 arguments = Handle<Object>( 7848 arguments = Handle<Object>(
7523 Accessors::FunctionGetArguments(*function, 7849 Accessors::FunctionGetArguments(*function,
7524 NULL)->ToObjectUnchecked()); 7850 NULL)->ToObjectUnchecked());
7525 ASSERT(*arguments != isolate->heap()->null_value()); 7851 ASSERT(*arguments != isolate->heap()->null_value());
7526 ASSERT(*arguments != isolate->heap()->undefined_value()); 7852 ASSERT(*arguments != isolate->heap()->undefined_value());
7527 } 7853 }
7528 frame->SetExpression(i, *arguments); 7854 frame->SetExpression(i, *arguments);
7529 } 7855 }
7530 } 7856 }
7531 7857
7532 isolate->compilation_cache()->MarkForLazyOptimizing(function);
7533 if (type == Deoptimizer::EAGER) { 7858 if (type == Deoptimizer::EAGER) {
7534 RUNTIME_ASSERT(function->IsOptimized()); 7859 RUNTIME_ASSERT(function->IsOptimized());
7535 } else { 7860 } else {
7536 RUNTIME_ASSERT(!function->IsOptimized()); 7861 RUNTIME_ASSERT(!function->IsOptimized());
7537 } 7862 }
7538 7863
7539 // Avoid doing too much work when running with --always-opt and keep 7864 // Avoid doing too much work when running with --always-opt and keep
7540 // the optimized code around. 7865 // the optimized code around.
7541 if (FLAG_always_opt || type == Deoptimizer::LAZY) { 7866 if (FLAG_always_opt || type == Deoptimizer::LAZY) {
7542 return isolate->heap()->undefined_value(); 7867 return isolate->heap()->undefined_value();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
7578 ASSERT(args.length() == 1); 7903 ASSERT(args.length() == 1);
7579 CONVERT_ARG_CHECKED(JSFunction, function, 0); 7904 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7580 if (!function->IsOptimized()) return isolate->heap()->undefined_value(); 7905 if (!function->IsOptimized()) return isolate->heap()->undefined_value();
7581 7906
7582 Deoptimizer::DeoptimizeFunction(*function); 7907 Deoptimizer::DeoptimizeFunction(*function);
7583 7908
7584 return isolate->heap()->undefined_value(); 7909 return isolate->heap()->undefined_value();
7585 } 7910 }
7586 7911
7587 7912
7913 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
7914 #if defined(USE_SIMULATOR)
7915 return isolate->heap()->true_value();
7916 #else
7917 return isolate->heap()->false_value();
7918 #endif
7919 }
7920
7921
7588 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) { 7922 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
7589 HandleScope scope(isolate); 7923 HandleScope scope(isolate);
7590 ASSERT(args.length() == 1); 7924 ASSERT(args.length() == 1);
7591 CONVERT_ARG_CHECKED(JSFunction, function, 0); 7925 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7592 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 7926 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
7593 function->MarkForLazyRecompilation(); 7927 function->MarkForLazyRecompilation();
7594 return isolate->heap()->undefined_value(); 7928 return isolate->heap()->undefined_value();
7595 } 7929 }
7596 7930
7597 7931
(...skipping 19 matching lines...) Expand all
7617 return Smi::FromInt(function->shared()->opt_count()); 7951 return Smi::FromInt(function->shared()->opt_count());
7618 } 7952 }
7619 7953
7620 7954
7621 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { 7955 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
7622 HandleScope scope(isolate); 7956 HandleScope scope(isolate);
7623 ASSERT(args.length() == 1); 7957 ASSERT(args.length() == 1);
7624 CONVERT_ARG_CHECKED(JSFunction, function, 0); 7958 CONVERT_ARG_CHECKED(JSFunction, function, 0);
7625 7959
7626 // We're not prepared to handle a function with arguments object. 7960 // We're not prepared to handle a function with arguments object.
7627 ASSERT(!function->shared()->scope_info()->HasArgumentsShadow()); 7961 ASSERT(!function->shared()->uses_arguments());
7628 7962
7629 // We have hit a back edge in an unoptimized frame for a function that was 7963 // We have hit a back edge in an unoptimized frame for a function that was
7630 // selected for on-stack replacement. Find the unoptimized code object. 7964 // selected for on-stack replacement. Find the unoptimized code object.
7631 Handle<Code> unoptimized(function->shared()->code(), isolate); 7965 Handle<Code> unoptimized(function->shared()->code(), isolate);
7632 // Keep track of whether we've succeeded in optimizing. 7966 // Keep track of whether we've succeeded in optimizing.
7633 bool succeeded = unoptimized->optimizable(); 7967 bool succeeded = unoptimized->optimizable();
7634 if (succeeded) { 7968 if (succeeded) {
7635 // If we are trying to do OSR when there are already optimized 7969 // If we are trying to do OSR when there are already optimized
7636 // activations of the function, it means (a) the function is directly or 7970 // activations of the function, it means (a) the function is directly or
7637 // indirectly recursive and (b) an optimized invocation has been 7971 // indirectly recursive and (b) an optimized invocation has been
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
7741 8075
7742 8076
7743 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) { 8077 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
7744 HandleScope scope(isolate); 8078 HandleScope scope(isolate);
7745 ASSERT(args.length() == 1); 8079 ASSERT(args.length() == 1);
7746 RUNTIME_ASSERT(!args[0]->IsJSFunction()); 8080 RUNTIME_ASSERT(!args[0]->IsJSFunction());
7747 return *Execution::GetConstructorDelegate(args.at<Object>(0)); 8081 return *Execution::GetConstructorDelegate(args.at<Object>(0));
7748 } 8082 }
7749 8083
7750 8084
7751 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) { 8085 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
7752 NoHandleAllocation ha; 8086 NoHandleAllocation ha;
7753 ASSERT(args.length() == 1); 8087 ASSERT(args.length() == 1);
7754 8088
7755 CONVERT_CHECKED(JSFunction, function, args[0]); 8089 CONVERT_CHECKED(JSFunction, function, args[0]);
7756 int length = function->shared()->scope_info()->NumberOfContextSlots(); 8090 int length = function->shared()->scope_info()->NumberOfContextSlots();
7757 Object* result; 8091 Object* result;
7758 { MaybeObject* maybe_result = 8092 { MaybeObject* maybe_result =
7759 isolate->heap()->AllocateFunctionContext(length, function); 8093 isolate->heap()->AllocateFunctionContext(length, function);
7760 if (!maybe_result->ToObject(&result)) return maybe_result; 8094 if (!maybe_result->ToObject(&result)) return maybe_result;
7761 } 8095 }
7762 8096
7763 isolate->set_context(Context::cast(result)); 8097 isolate->set_context(Context::cast(result));
7764 8098
7765 return result; // non-failure 8099 return result; // non-failure
7766 } 8100 }
7767 8101
7768 8102
7769 MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate, 8103 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
7770 Object* object, 8104 NoHandleAllocation ha;
7771 bool is_catch_context) { 8105 ASSERT(args.length() == 2);
7772 // Convert the object to a proper JavaScript object. 8106 JSObject* extension_object;
7773 Object* js_object = object; 8107 if (args[0]->IsJSObject()) {
7774 if (!js_object->IsJSObject()) { 8108 extension_object = JSObject::cast(args[0]);
7775 MaybeObject* maybe_js_object = js_object->ToObject(); 8109 } else {
7776 if (!maybe_js_object->ToObject(&js_object)) { 8110 // Convert the object to a proper JavaScript object.
7777 if (!Failure::cast(maybe_js_object)->IsInternalError()) { 8111 MaybeObject* maybe_js_object = args[0]->ToObject();
8112 if (!maybe_js_object->To(&extension_object)) {
8113 if (Failure::cast(maybe_js_object)->IsInternalError()) {
8114 HandleScope scope(isolate);
8115 Handle<Object> handle = args.at<Object>(0);
8116 Handle<Object> result =
8117 isolate->factory()->NewTypeError("with_expression",
8118 HandleVector(&handle, 1));
8119 return isolate->Throw(*result);
8120 } else {
7778 return maybe_js_object; 8121 return maybe_js_object;
7779 } 8122 }
7780 HandleScope scope(isolate);
7781 Handle<Object> handle(object, isolate);
7782 Handle<Object> result =
7783 isolate->factory()->NewTypeError("with_expression",
7784 HandleVector(&handle, 1));
7785 return isolate->Throw(*result);
7786 } 8123 }
7787 } 8124 }
7788 8125
7789 Object* result; 8126 JSFunction* function;
7790 { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext( 8127 if (args[1]->IsSmi()) {
7791 isolate->context(), JSObject::cast(js_object), is_catch_context); 8128 // A smi sentinel indicates a context nested inside global code rather
7792 if (!maybe_result->ToObject(&result)) return maybe_result; 8129 // than some function. There is a canonical empty function that can be
8130 // gotten from the global context.
8131 function = isolate->context()->global_context()->closure();
8132 } else {
8133 function = JSFunction::cast(args[1]);
7793 } 8134 }
7794 8135
7795 Context* context = Context::cast(result); 8136 Context* context;
8137 MaybeObject* maybe_context =
8138 isolate->heap()->AllocateWithContext(function,
8139 isolate->context(),
8140 extension_object);
8141 if (!maybe_context->To(&context)) return maybe_context;
7796 isolate->set_context(context); 8142 isolate->set_context(context);
7797 8143 return context;
7798 return result;
7799 }
7800
7801
7802 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushContext) {
7803 NoHandleAllocation ha;
7804 ASSERT(args.length() == 1);
7805 return PushContextHelper(isolate, args[0], false);
7806 } 8144 }
7807 8145
7808 8146
7809 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { 8147 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
7810 NoHandleAllocation ha; 8148 NoHandleAllocation ha;
7811 ASSERT(args.length() == 1); 8149 ASSERT(args.length() == 3);
7812 return PushContextHelper(isolate, args[0], true); 8150 String* name = String::cast(args[0]);
8151 Object* thrown_object = args[1];
8152 JSFunction* function;
8153 if (args[2]->IsSmi()) {
8154 // A smi sentinel indicates a context nested inside global code rather
8155 // than some function. There is a canonical empty function that can be
8156 // gotten from the global context.
8157 function = isolate->context()->global_context()->closure();
8158 } else {
8159 function = JSFunction::cast(args[2]);
8160 }
8161 Context* context;
8162 MaybeObject* maybe_context =
8163 isolate->heap()->AllocateCatchContext(function,
8164 isolate->context(),
8165 name,
8166 thrown_object);
8167 if (!maybe_context->To(&context)) return maybe_context;
8168 isolate->set_context(context);
8169 return context;
7813 } 8170 }
7814 8171
7815 8172
7816 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { 8173 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7817 HandleScope scope(isolate); 8174 HandleScope scope(isolate);
7818 ASSERT(args.length() == 2); 8175 ASSERT(args.length() == 2);
7819 8176
7820 CONVERT_ARG_CHECKED(Context, context, 0); 8177 CONVERT_ARG_CHECKED(Context, context, 0);
7821 CONVERT_ARG_CHECKED(String, name, 1); 8178 CONVERT_ARG_CHECKED(String, name, 1);
7822 8179
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
7992 } 8349 }
7993 8350
7994 8351
7995 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) { 8352 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
7996 HandleScope scope(isolate); 8353 HandleScope scope(isolate);
7997 ASSERT(args.length() == 4); 8354 ASSERT(args.length() == 4);
7998 8355
7999 Handle<Object> value(args[0], isolate); 8356 Handle<Object> value(args[0], isolate);
8000 CONVERT_ARG_CHECKED(Context, context, 1); 8357 CONVERT_ARG_CHECKED(Context, context, 1);
8001 CONVERT_ARG_CHECKED(String, name, 2); 8358 CONVERT_ARG_CHECKED(String, name, 2);
8002 CONVERT_SMI_CHECKED(strict_unchecked, args[3]); 8359 CONVERT_SMI_ARG_CHECKED(strict_unchecked, 3);
8003 RUNTIME_ASSERT(strict_unchecked == kStrictMode || 8360 RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
8004 strict_unchecked == kNonStrictMode); 8361 strict_unchecked == kNonStrictMode);
8005 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); 8362 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
8006 8363
8007 int index; 8364 int index;
8008 PropertyAttributes attributes; 8365 PropertyAttributes attributes;
8009 ContextLookupFlags flags = FOLLOW_CHAINS; 8366 ContextLookupFlags flags = FOLLOW_CHAINS;
8010 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); 8367 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8011 8368
8012 if (index >= 0) { 8369 if (index >= 0) {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
8306 } else { 8663 } else {
8307 return isolate->heap()->null_value(); 8664 return isolate->heap()->null_value();
8308 } 8665 }
8309 } 8666 }
8310 8667
8311 8668
8312 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) { 8669 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
8313 NoHandleAllocation ha; 8670 NoHandleAllocation ha;
8314 ASSERT(args.length() == 1); 8671 ASSERT(args.length() == 1);
8315 8672
8316 CONVERT_DOUBLE_CHECKED(x, args[0]); 8673 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8317 const char* zone = OS::LocalTimezone(x); 8674 const char* zone = OS::LocalTimezone(x);
8318 return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone)); 8675 return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
8319 } 8676 }
8320 8677
8321 8678
8322 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimeOffset) { 8679 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimeOffset) {
8323 NoHandleAllocation ha; 8680 NoHandleAllocation ha;
8324 ASSERT(args.length() == 0); 8681 ASSERT(args.length() == 0);
8325 8682
8326 return isolate->heap()->NumberFromDouble(OS::LocalTimeOffset()); 8683 return isolate->heap()->NumberFromDouble(OS::LocalTimeOffset());
8327 } 8684 }
8328 8685
8329 8686
8330 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateDaylightSavingsOffset) { 8687 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateDaylightSavingsOffset) {
8331 NoHandleAllocation ha; 8688 NoHandleAllocation ha;
8332 ASSERT(args.length() == 1); 8689 ASSERT(args.length() == 1);
8333 8690
8334 CONVERT_DOUBLE_CHECKED(x, args[0]); 8691 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8335 return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x)); 8692 return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x));
8336 } 8693 }
8337 8694
8338 8695
8339 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) { 8696 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
8340 ASSERT(args.length() == 1); 8697 ASSERT(args.length() == 1);
8341 Object* global = args[0]; 8698 Object* global = args[0];
8342 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); 8699 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
8343 return JSGlobalObject::cast(global)->global_receiver(); 8700 return JSGlobalObject::cast(global)->global_receiver();
8344 } 8701 }
8345 8702
8346 8703
8347 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { 8704 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
8348 HandleScope scope(isolate); 8705 HandleScope scope(isolate);
8349 ASSERT_EQ(1, args.length()); 8706 ASSERT_EQ(1, args.length());
8350 CONVERT_ARG_CHECKED(String, source, 0); 8707 CONVERT_ARG_CHECKED(String, source, 0);
8351 8708
8352 Handle<Object> result = JsonParser::Parse(source); 8709 source = Handle<String>(source->TryFlattenGetString());
8710 // Optimized fast case where we only have ascii characters.
8711 Handle<Object> result;
8712 if (source->IsSeqAsciiString()) {
8713 result = JsonParser<true>::Parse(source);
8714 } else {
8715 result = JsonParser<false>::Parse(source);
8716 }
8353 if (result.is_null()) { 8717 if (result.is_null()) {
8354 // Syntax error or stack overflow in scanner. 8718 // Syntax error or stack overflow in scanner.
8355 ASSERT(isolate->has_pending_exception()); 8719 ASSERT(isolate->has_pending_exception());
8356 return Failure::Exception(); 8720 return Failure::Exception();
8357 } 8721 }
8358 return *result; 8722 return *result;
8359 } 8723 }
8360 8724
8361 8725
8362 bool CodeGenerationFromStringsAllowed(Isolate* isolate, 8726 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
8458 // it is bound in the global context. 8822 // it is bound in the global context.
8459 int index = -1; 8823 int index = -1;
8460 PropertyAttributes attributes = ABSENT; 8824 PropertyAttributes attributes = ABSENT;
8461 while (true) { 8825 while (true) {
8462 receiver = context->Lookup(isolate->factory()->eval_symbol(), 8826 receiver = context->Lookup(isolate->factory()->eval_symbol(),
8463 FOLLOW_PROTOTYPE_CHAIN, 8827 FOLLOW_PROTOTYPE_CHAIN,
8464 &index, &attributes); 8828 &index, &attributes);
8465 // Stop search when eval is found or when the global context is 8829 // Stop search when eval is found or when the global context is
8466 // reached. 8830 // reached.
8467 if (attributes != ABSENT || context->IsGlobalContext()) break; 8831 if (attributes != ABSENT || context->IsGlobalContext()) break;
8468 if (context->is_function_context()) { 8832 context = Handle<Context>(context->previous(), isolate);
8469 context = Handle<Context>(Context::cast(context->closure()->context()),
8470 isolate);
8471 } else {
8472 context = Handle<Context>(context->previous(), isolate);
8473 }
8474 } 8833 }
8475 8834
8476 // If eval could not be resolved, it has been deleted and we need to 8835 // If eval could not be resolved, it has been deleted and we need to
8477 // throw a reference error. 8836 // throw a reference error.
8478 if (attributes == ABSENT) { 8837 if (attributes == ABSENT) {
8479 Handle<Object> name = isolate->factory()->eval_symbol(); 8838 Handle<Object> name = isolate->factory()->eval_symbol();
8480 Handle<Object> reference_error = 8839 Handle<Object> reference_error =
8481 isolate->factory()->NewReferenceError("not_defined", 8840 isolate->factory()->NewReferenceError("not_defined",
8482 HandleVector(&name, 1)); 8841 HandleVector(&name, 1));
8483 return MakePair(isolate->Throw(*reference_error), NULL); 8842 return MakePair(isolate->Throw(*reference_error), NULL);
(...skipping 12 matching lines...) Expand all
8496 // Compare it to the builtin 'GlobalEval' function to make sure. 8855 // Compare it to the builtin 'GlobalEval' function to make sure.
8497 if (*callee != isolate->global_context()->global_eval_fun() || 8856 if (*callee != isolate->global_context()->global_eval_fun() ||
8498 !args[1]->IsString()) { 8857 !args[1]->IsString()) {
8499 return MakePair(*callee, isolate->heap()->the_hole_value()); 8858 return MakePair(*callee, isolate->heap()->the_hole_value());
8500 } 8859 }
8501 8860
8502 ASSERT(args[3]->IsSmi()); 8861 ASSERT(args[3]->IsSmi());
8503 return CompileGlobalEval(isolate, 8862 return CompileGlobalEval(isolate,
8504 args.at<String>(1), 8863 args.at<String>(1),
8505 args.at<Object>(2), 8864 args.at<Object>(2),
8506 static_cast<StrictModeFlag>( 8865 static_cast<StrictModeFlag>(args.smi_at(3)));
8507 Smi::cast(args[3])->value()));
8508 } 8866 }
8509 8867
8510 8868
8511 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { 8869 RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
8512 ASSERT(args.length() == 4); 8870 ASSERT(args.length() == 4);
8513 8871
8514 HandleScope scope(isolate); 8872 HandleScope scope(isolate);
8515 Handle<Object> callee = args.at<Object>(0); 8873 Handle<Object> callee = args.at<Object>(0);
8516 8874
8517 // 'eval' is bound in the global context, but it may have been overwritten. 8875 // 'eval' is bound in the global context, but it may have been overwritten.
8518 // Compare it to the builtin 'GlobalEval' function to make sure. 8876 // Compare it to the builtin 'GlobalEval' function to make sure.
8519 if (*callee != isolate->global_context()->global_eval_fun() || 8877 if (*callee != isolate->global_context()->global_eval_fun() ||
8520 !args[1]->IsString()) { 8878 !args[1]->IsString()) {
8521 return MakePair(*callee, isolate->heap()->the_hole_value()); 8879 return MakePair(*callee, isolate->heap()->the_hole_value());
8522 } 8880 }
8523 8881
8524 ASSERT(args[3]->IsSmi()); 8882 ASSERT(args[3]->IsSmi());
8525 return CompileGlobalEval(isolate, 8883 return CompileGlobalEval(isolate,
8526 args.at<String>(1), 8884 args.at<String>(1),
8527 args.at<Object>(2), 8885 args.at<Object>(2),
8528 static_cast<StrictModeFlag>( 8886 static_cast<StrictModeFlag>(args.smi_at(3)));
8529 Smi::cast(args[3])->value()));
8530 } 8887 }
8531 8888
8532 8889
8533 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNewFunctionAttributes) { 8890 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNewFunctionAttributes) {
8534 // This utility adjusts the property attributes for newly created Function 8891 // This utility adjusts the property attributes for newly created Function
8535 // object ("new Function(...)") by changing the map. 8892 // object ("new Function(...)") by changing the map.
8536 // All it does is changing the prototype property to enumerable 8893 // All it does is changing the prototype property to enumerable
8537 // as specified in ECMA262, 15.3.5.2. 8894 // as specified in ECMA262, 15.3.5.2.
8538 HandleScope scope(isolate); 8895 HandleScope scope(isolate);
8539 ASSERT(args.length() == 1); 8896 ASSERT(args.length() == 1);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
8580 CONVERT_CHECKED(JSArray, array, args[0]); 8937 CONVERT_CHECKED(JSArray, array, args[0]);
8581 CONVERT_CHECKED(JSObject, element, args[1]); 8938 CONVERT_CHECKED(JSObject, element, args[1]);
8582 RUNTIME_ASSERT(array->HasFastElements()); 8939 RUNTIME_ASSERT(array->HasFastElements());
8583 int length = Smi::cast(array->length())->value(); 8940 int length = Smi::cast(array->length())->value();
8584 FixedArray* elements = FixedArray::cast(array->elements()); 8941 FixedArray* elements = FixedArray::cast(array->elements());
8585 for (int i = 0; i < length; i++) { 8942 for (int i = 0; i < length; i++) {
8586 if (elements->get(i) == element) return isolate->heap()->false_value(); 8943 if (elements->get(i) == element) return isolate->heap()->false_value();
8587 } 8944 }
8588 Object* obj; 8945 Object* obj;
8589 // Strict not needed. Used for cycle detection in Array join implementation. 8946 // Strict not needed. Used for cycle detection in Array join implementation.
8590 { MaybeObject* maybe_obj = array->SetFastElement(length, element, 8947 { MaybeObject* maybe_obj =
8591 kNonStrictMode); 8948 array->SetFastElement(length, element, kNonStrictMode, true);
8592 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8949 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8593 } 8950 }
8594 return isolate->heap()->true_value(); 8951 return isolate->heap()->true_value();
8595 } 8952 }
8596 8953
8597 8954
8598 /** 8955 /**
8599 * A simple visitor visits every element of Array's. 8956 * A simple visitor visits every element of Array's.
8600 * The backend storage can be a fixed array for fast elements case, 8957 * The backend storage can be a fixed array for fast elements case,
8601 * or a dictionary for sparse array. Since Dictionary is a subtype 8958 * or a dictionary for sparse array. Since Dictionary is a subtype
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
9607 if (!maybe_result->ToObject(&result)) return maybe_result; 9964 if (!maybe_result->ToObject(&result)) return maybe_result;
9608 } 9965 }
9609 9966
9610 // Count all frames which are relevant to debugging stack trace. 9967 // Count all frames which are relevant to debugging stack trace.
9611 int n = 0; 9968 int n = 0;
9612 StackFrame::Id id = isolate->debug()->break_frame_id(); 9969 StackFrame::Id id = isolate->debug()->break_frame_id();
9613 if (id == StackFrame::NO_ID) { 9970 if (id == StackFrame::NO_ID) {
9614 // If there is no JavaScript stack frame count is 0. 9971 // If there is no JavaScript stack frame count is 0.
9615 return Smi::FromInt(0); 9972 return Smi::FromInt(0);
9616 } 9973 }
9617 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++; 9974
9975 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
9976 n += it.frame()->GetInlineCount();
9977 }
9618 return Smi::FromInt(n); 9978 return Smi::FromInt(n);
9619 } 9979 }
9620 9980
9621 9981
9622 static const int kFrameDetailsFrameIdIndex = 0; 9982 static const int kFrameDetailsFrameIdIndex = 0;
9623 static const int kFrameDetailsReceiverIndex = 1; 9983 static const int kFrameDetailsReceiverIndex = 1;
9624 static const int kFrameDetailsFunctionIndex = 2; 9984 static const int kFrameDetailsFunctionIndex = 2;
9625 static const int kFrameDetailsArgumentCountIndex = 3; 9985 static const int kFrameDetailsArgumentCountIndex = 3;
9626 static const int kFrameDetailsLocalCountIndex = 4; 9986 static const int kFrameDetailsLocalCountIndex = 4;
9627 static const int kFrameDetailsSourcePositionIndex = 5; 9987 static const int kFrameDetailsSourcePositionIndex = 5;
9628 static const int kFrameDetailsConstructCallIndex = 6; 9988 static const int kFrameDetailsConstructCallIndex = 6;
9629 static const int kFrameDetailsAtReturnIndex = 7; 9989 static const int kFrameDetailsAtReturnIndex = 7;
9630 static const int kFrameDetailsDebuggerFrameIndex = 8; 9990 static const int kFrameDetailsFlagsIndex = 8;
9631 static const int kFrameDetailsFirstDynamicIndex = 9; 9991 static const int kFrameDetailsFirstDynamicIndex = 9;
9632 9992
9633 // Return an array with frame details 9993 // Return an array with frame details
9634 // args[0]: number: break id 9994 // args[0]: number: break id
9635 // args[1]: number: frame index 9995 // args[1]: number: frame index
9636 // 9996 //
9637 // The array returned contains the following information: 9997 // The array returned contains the following information:
9638 // 0: Frame id 9998 // 0: Frame id
9639 // 1: Receiver 9999 // 1: Receiver
9640 // 2: Function 10000 // 2: Function
9641 // 3: Argument count 10001 // 3: Argument count
9642 // 4: Local count 10002 // 4: Local count
9643 // 5: Source position 10003 // 5: Source position
9644 // 6: Constructor call 10004 // 6: Constructor call
9645 // 7: Is at return 10005 // 7: Is at return
9646 // 8: Debugger frame 10006 // 8: Flags
9647 // Arguments name, value 10007 // Arguments name, value
9648 // Locals name, value 10008 // Locals name, value
9649 // Return value if any 10009 // Return value if any
9650 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { 10010 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9651 HandleScope scope(isolate); 10011 HandleScope scope(isolate);
9652 ASSERT(args.length() == 2); 10012 ASSERT(args.length() == 2);
9653 10013
9654 // Check arguments. 10014 // Check arguments.
9655 Object* check; 10015 Object* check;
9656 { MaybeObject* maybe_check = Runtime_CheckExecutionState( 10016 { MaybeObject* maybe_check = Runtime_CheckExecutionState(
9657 RUNTIME_ARGUMENTS(isolate, args)); 10017 RUNTIME_ARGUMENTS(isolate, args));
9658 if (!maybe_check->ToObject(&check)) return maybe_check; 10018 if (!maybe_check->ToObject(&check)) return maybe_check;
9659 } 10019 }
9660 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); 10020 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
9661 Heap* heap = isolate->heap(); 10021 Heap* heap = isolate->heap();
9662 10022
9663 // Find the relevant frame with the requested index. 10023 // Find the relevant frame with the requested index.
9664 StackFrame::Id id = isolate->debug()->break_frame_id(); 10024 StackFrame::Id id = isolate->debug()->break_frame_id();
9665 if (id == StackFrame::NO_ID) { 10025 if (id == StackFrame::NO_ID) {
9666 // If there are no JavaScript stack frames return undefined. 10026 // If there are no JavaScript stack frames return undefined.
9667 return heap->undefined_value(); 10027 return heap->undefined_value();
9668 } 10028 }
10029
10030 int deoptimized_frame_index = -1; // Frame index in optimized frame.
10031 DeoptimizedFrameInfo* deoptimized_frame = NULL;
10032
9669 int count = 0; 10033 int count = 0;
9670 JavaScriptFrameIterator it(isolate, id); 10034 JavaScriptFrameIterator it(isolate, id);
9671 for (; !it.done(); it.Advance()) { 10035 for (; !it.done(); it.Advance()) {
9672 if (count == index) break; 10036 if (index < count + it.frame()->GetInlineCount()) break;
9673 count++; 10037 count += it.frame()->GetInlineCount();
9674 } 10038 }
9675 if (it.done()) return heap->undefined_value(); 10039 if (it.done()) return heap->undefined_value();
9676 10040
9677 bool is_optimized_frame = 10041 if (it.frame()->is_optimized()) {
9678 it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION; 10042 deoptimized_frame_index =
10043 it.frame()->GetInlineCount() - (index - count) - 1;
10044 deoptimized_frame = Deoptimizer::DebuggerInspectableFrame(
10045 it.frame(),
10046 deoptimized_frame_index,
10047 isolate);
10048 }
9679 10049
9680 // Traverse the saved contexts chain to find the active context for the 10050 // Traverse the saved contexts chain to find the active context for the
9681 // selected frame. 10051 // selected frame.
9682 SaveContext* save = isolate->save_context(); 10052 SaveContext* save = isolate->save_context();
9683 while (save != NULL && !save->below(it.frame())) { 10053 while (save != NULL && !save->below(it.frame())) {
9684 save = save->prev(); 10054 save = save->prev();
9685 } 10055 }
9686 ASSERT(save != NULL); 10056 ASSERT(save != NULL);
9687 10057
9688 // Get the frame id. 10058 // Get the frame id.
9689 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); 10059 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
9690 10060
9691 // Find source position. 10061 // Find source position.
9692 int position = 10062 int position =
9693 it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); 10063 it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
9694 10064
9695 // Check for constructor frame. 10065 // Check for constructor frame. Inlined frames cannot be construct calls.
9696 bool constructor = it.frame()->IsConstructor(); 10066 bool inlined_frame =
10067 it.frame()->is_optimized() && deoptimized_frame_index != 0;
10068 bool constructor = !inlined_frame && it.frame()->IsConstructor();
9697 10069
9698 // Get scope info and read from it for local variable information. 10070 // Get scope info and read from it for local variable information.
9699 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); 10071 Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
9700 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); 10072 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
10073 ASSERT(*scope_info != SerializedScopeInfo::Empty());
9701 ScopeInfo<> info(*scope_info); 10074 ScopeInfo<> info(*scope_info);
9702 10075
9703 // Get the context.
9704 Handle<Context> context(Context::cast(it.frame()->context()));
9705
9706 // Get the locals names and values into a temporary array. 10076 // Get the locals names and values into a temporary array.
9707 // 10077 //
9708 // TODO(1240907): Hide compiler-introduced stack variables 10078 // TODO(1240907): Hide compiler-introduced stack variables
9709 // (e.g. .result)? For users of the debugger, they will probably be 10079 // (e.g. .result)? For users of the debugger, they will probably be
9710 // confusing. 10080 // confusing.
9711 Handle<FixedArray> locals = 10081 Handle<FixedArray> locals =
9712 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); 10082 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
9713 10083
9714 // Fill in the names of the locals. 10084 // Fill in the values of the locals.
9715 for (int i = 0; i < info.NumberOfLocals(); i++) { 10085 int i = 0;
10086 for (; i < info.number_of_stack_slots(); ++i) {
10087 // Use the value from the stack.
9716 locals->set(i * 2, *info.LocalName(i)); 10088 locals->set(i * 2, *info.LocalName(i));
9717 } 10089 if (it.frame()->is_optimized()) {
9718 10090 // Get the value from the deoptimized frame.
9719 // Fill in the values of the locals. 10091 locals->set(i * 2 + 1,
9720 for (int i = 0; i < info.NumberOfLocals(); i++) { 10092 deoptimized_frame->GetExpression(i));
9721 if (is_optimized_frame) { 10093 } else {
9722 // If we are inspecting an optimized frame use undefined as the
9723 // value for all locals.
9724 //
9725 // TODO(1140): We should be able to get the correct values
9726 // for locals in optimized frames.
9727 locals->set(i * 2 + 1, isolate->heap()->undefined_value());
9728 } else if (i < info.number_of_stack_slots()) {
9729 // Get the value from the stack. 10094 // Get the value from the stack.
9730 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); 10095 locals->set(i * 2 + 1, it.frame()->GetExpression(i));
9731 } else { 10096 }
9732 // Traverse the context chain to the function context as all local 10097 }
9733 // variables stored in the context will be on the function context. 10098 if (i < info.NumberOfLocals()) {
10099 // Get the context containing declarations.
10100 Handle<Context> context(
10101 Context::cast(it.frame()->context())->declaration_context());
10102 for (; i < info.NumberOfLocals(); ++i) {
9734 Handle<String> name = info.LocalName(i); 10103 Handle<String> name = info.LocalName(i);
9735 while (!context->is_function_context()) { 10104 locals->set(i * 2, *name);
9736 context = Handle<Context>(context->previous());
9737 }
9738 ASSERT(context->is_function_context());
9739 locals->set(i * 2 + 1, 10105 locals->set(i * 2 + 1,
9740 context->get(scope_info->ContextSlotIndex(*name, NULL))); 10106 context->get(scope_info->ContextSlotIndex(*name, NULL)));
9741 } 10107 }
9742 } 10108 }
9743 10109
9744 // Check whether this frame is positioned at return. If not top 10110 // Check whether this frame is positioned at return. If not top
9745 // frame or if the frame is optimized it cannot be at a return. 10111 // frame or if the frame is optimized it cannot be at a return.
9746 bool at_return = false; 10112 bool at_return = false;
9747 if (!is_optimized_frame && index == 0) { 10113 if (!it.frame()->is_optimized() && index == 0) {
9748 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); 10114 at_return = isolate->debug()->IsBreakAtReturn(it.frame());
9749 } 10115 }
9750 10116
9751 // If positioned just before return find the value to be returned and add it 10117 // If positioned just before return find the value to be returned and add it
9752 // to the frame information. 10118 // to the frame information.
9753 Handle<Object> return_value = isolate->factory()->undefined_value(); 10119 Handle<Object> return_value = isolate->factory()->undefined_value();
9754 if (at_return) { 10120 if (at_return) {
9755 StackFrameIterator it2(isolate); 10121 StackFrameIterator it2(isolate);
9756 Address internal_frame_sp = NULL; 10122 Address internal_frame_sp = NULL;
9757 while (!it2.done()) { 10123 while (!it2.done()) {
(...skipping 24 matching lines...) Expand all
9782 10148
9783 // Now advance to the arguments adapter frame (if any). It contains all 10149 // Now advance to the arguments adapter frame (if any). It contains all
9784 // the provided parameters whereas the function frame always have the number 10150 // the provided parameters whereas the function frame always have the number
9785 // of arguments matching the functions parameters. The rest of the 10151 // of arguments matching the functions parameters. The rest of the
9786 // information (except for what is collected above) is the same. 10152 // information (except for what is collected above) is the same.
9787 it.AdvanceToArgumentsFrame(); 10153 it.AdvanceToArgumentsFrame();
9788 10154
9789 // Find the number of arguments to fill. At least fill the number of 10155 // Find the number of arguments to fill. At least fill the number of
9790 // parameters for the function and fill more if more parameters are provided. 10156 // parameters for the function and fill more if more parameters are provided.
9791 int argument_count = info.number_of_parameters(); 10157 int argument_count = info.number_of_parameters();
9792 if (argument_count < it.frame()->ComputeParametersCount()) { 10158 if (it.frame()->is_optimized()) {
9793 argument_count = it.frame()->ComputeParametersCount(); 10159 ASSERT_EQ(argument_count, deoptimized_frame->parameters_count());
10160 } else {
10161 if (argument_count < it.frame()->ComputeParametersCount()) {
10162 argument_count = it.frame()->ComputeParametersCount();
10163 }
9794 } 10164 }
9795 10165
9796 // Calculate the size of the result. 10166 // Calculate the size of the result.
9797 int details_size = kFrameDetailsFirstDynamicIndex + 10167 int details_size = kFrameDetailsFirstDynamicIndex +
9798 2 * (argument_count + info.NumberOfLocals()) + 10168 2 * (argument_count + info.NumberOfLocals()) +
9799 (at_return ? 1 : 0); 10169 (at_return ? 1 : 0);
9800 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); 10170 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
9801 10171
9802 // Add the frame id. 10172 // Add the frame id.
9803 details->set(kFrameDetailsFrameIdIndex, *frame_id); 10173 details->set(kFrameDetailsFrameIdIndex, *frame_id);
9804 10174
9805 // Add the function (same as in function frame). 10175 // Add the function (same as in function frame).
9806 details->set(kFrameDetailsFunctionIndex, it.frame()->function()); 10176 if (it.frame()->is_optimized()) {
10177 // Get the function from the deoptimized frame.
10178 details->set(kFrameDetailsFunctionIndex, deoptimized_frame->GetFunction());
10179 } else {
10180 // Get the function from the stack.
10181 details->set(kFrameDetailsFunctionIndex, it.frame()->function());
10182 }
9807 10183
9808 // Add the arguments count. 10184 // Add the arguments count.
9809 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); 10185 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
9810 10186
9811 // Add the locals count 10187 // Add the locals count
9812 details->set(kFrameDetailsLocalCountIndex, 10188 details->set(kFrameDetailsLocalCountIndex,
9813 Smi::FromInt(info.NumberOfLocals())); 10189 Smi::FromInt(info.NumberOfLocals()));
9814 10190
9815 // Add the source position. 10191 // Add the source position.
9816 if (position != RelocInfo::kNoPosition) { 10192 if (position != RelocInfo::kNoPosition) {
9817 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); 10193 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
9818 } else { 10194 } else {
9819 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); 10195 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
9820 } 10196 }
9821 10197
9822 // Add the constructor information. 10198 // Add the constructor information.
9823 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); 10199 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
9824 10200
9825 // Add the at return information. 10201 // Add the at return information.
9826 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return)); 10202 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
9827 10203
9828 // Add information on whether this frame is invoked in the debugger context. 10204 // Add flags to indicate information on whether this frame is
9829 details->set(kFrameDetailsDebuggerFrameIndex, 10205 // bit 0: invoked in the debugger context.
9830 heap->ToBoolean(*save->context() == 10206 // bit 1: optimized frame.
9831 *isolate->debug()->debug_context())); 10207 // bit 2: inlined in optimized frame
10208 int flags = 0;
10209 if (*save->context() == *isolate->debug()->debug_context()) {
10210 flags |= 1 << 0;
10211 }
10212 if (it.frame()->is_optimized()) {
10213 flags |= 1 << 1;
10214 if (deoptimized_frame_index > 0) {
10215 flags |= 1 << 2;
10216 }
10217 }
10218 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
9832 10219
9833 // Fill the dynamic part. 10220 // Fill the dynamic part.
9834 int details_index = kFrameDetailsFirstDynamicIndex; 10221 int details_index = kFrameDetailsFirstDynamicIndex;
9835 10222
9836 // Add arguments name and value. 10223 // Add arguments name and value.
9837 for (int i = 0; i < argument_count; i++) { 10224 for (int i = 0; i < argument_count; i++) {
9838 // Name of the argument. 10225 // Name of the argument.
9839 if (i < info.number_of_parameters()) { 10226 if (i < info.number_of_parameters()) {
9840 details->set(details_index++, *info.parameter_name(i)); 10227 details->set(details_index++, *info.parameter_name(i));
9841 } else { 10228 } else {
9842 details->set(details_index++, heap->undefined_value()); 10229 details->set(details_index++, heap->undefined_value());
9843 } 10230 }
9844 10231
9845 // Parameter value. If we are inspecting an optimized frame, use 10232 // Parameter value.
9846 // undefined as the value. 10233 if (it.frame()->is_optimized()) {
9847 // 10234 // Get the value from the deoptimized frame.
9848 // TODO(3141533): We should be able to get the actual parameter 10235 details->set(details_index++, deoptimized_frame->GetParameter(i));
9849 // value for optimized frames.
9850 if (!is_optimized_frame &&
9851 (i < it.frame()->ComputeParametersCount())) {
9852 details->set(details_index++, it.frame()->GetParameter(i));
9853 } else { 10236 } else {
9854 details->set(details_index++, heap->undefined_value()); 10237 if (i < it.frame()->ComputeParametersCount()) {
10238 // Get the value from the stack.
10239 details->set(details_index++, it.frame()->GetParameter(i));
10240 } else {
10241 details->set(details_index++, heap->undefined_value());
10242 }
9855 } 10243 }
9856 } 10244 }
9857 10245
9858 // Add locals name and value from the temporary copy from the function frame. 10246 // Add locals name and value from the temporary copy from the function frame.
9859 for (int i = 0; i < info.NumberOfLocals() * 2; i++) { 10247 for (int i = 0; i < info.NumberOfLocals() * 2; i++) {
9860 details->set(details_index++, locals->get(i)); 10248 details->set(details_index++, locals->get(i));
9861 } 10249 }
9862 10250
9863 // Add the value being returned. 10251 // Add the value being returned.
9864 if (at_return) { 10252 if (at_return) {
(...skipping 11 matching lines...) Expand all
9876 // by creating correct wrapper object based on the calling frame's 10264 // by creating correct wrapper object based on the calling frame's
9877 // global context. 10265 // global context.
9878 it.Advance(); 10266 it.Advance();
9879 Handle<Context> calling_frames_global_context( 10267 Handle<Context> calling_frames_global_context(
9880 Context::cast(Context::cast(it.frame()->context())->global_context())); 10268 Context::cast(Context::cast(it.frame()->context())->global_context()));
9881 receiver = 10269 receiver =
9882 isolate->factory()->ToObject(receiver, calling_frames_global_context); 10270 isolate->factory()->ToObject(receiver, calling_frames_global_context);
9883 } 10271 }
9884 details->set(kFrameDetailsReceiverIndex, *receiver); 10272 details->set(kFrameDetailsReceiverIndex, *receiver);
9885 10273
10274 // Get rid of the calculated deoptimized frame if any.
10275 if (deoptimized_frame != NULL) {
10276 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame,
10277 isolate);
10278 }
10279
9886 ASSERT_EQ(details_size, details_index); 10280 ASSERT_EQ(details_size, details_index);
9887 return *isolate->factory()->NewJSArrayWithElements(details); 10281 return *isolate->factory()->NewJSArrayWithElements(details);
9888 } 10282 }
9889 10283
9890 10284
9891 // Copy all the context locals into an object used to materialize a scope. 10285 // Copy all the context locals into an object used to materialize a scope.
9892 static bool CopyContextLocalsToScopeObject( 10286 static bool CopyContextLocalsToScopeObject(
9893 Isolate* isolate, 10287 Isolate* isolate,
9894 Handle<SerializedScopeInfo> serialized_scope_info, 10288 Handle<SerializedScopeInfo> serialized_scope_info,
9895 ScopeInfo<>& scope_info, 10289 ScopeInfo<>& scope_info,
9896 Handle<Context> context, 10290 Handle<Context> context,
9897 Handle<JSObject> scope_object) { 10291 Handle<JSObject> scope_object) {
9898 // Fill all context locals to the context extension. 10292 // Fill all context locals to the context extension.
9899 for (int i = Context::MIN_CONTEXT_SLOTS; 10293 for (int i = Context::MIN_CONTEXT_SLOTS;
9900 i < scope_info.number_of_context_slots(); 10294 i < scope_info.number_of_context_slots();
9901 i++) { 10295 i++) {
9902 int context_index = serialized_scope_info->ContextSlotIndex( 10296 int context_index = serialized_scope_info->ContextSlotIndex(
9903 *scope_info.context_slot_name(i), NULL); 10297 *scope_info.context_slot_name(i), NULL);
9904 10298
9905 // Don't include the arguments shadow (.arguments) context variable. 10299 RETURN_IF_EMPTY_HANDLE_VALUE(
9906 if (*scope_info.context_slot_name(i) != 10300 isolate,
9907 isolate->heap()->arguments_shadow_symbol()) { 10301 SetProperty(scope_object,
9908 RETURN_IF_EMPTY_HANDLE_VALUE( 10302 scope_info.context_slot_name(i),
9909 isolate, 10303 Handle<Object>(context->get(context_index), isolate),
9910 SetProperty(scope_object, 10304 NONE,
9911 scope_info.context_slot_name(i), 10305 kNonStrictMode),
9912 Handle<Object>(context->get(context_index), isolate), 10306 false);
9913 NONE,
9914 kNonStrictMode),
9915 false);
9916 }
9917 } 10307 }
9918 10308
9919 return true; 10309 return true;
9920 } 10310 }
9921 10311
9922 10312
9923 // Create a plain JSObject which materializes the local scope for the specified 10313 // Create a plain JSObject which materializes the local scope for the specified
9924 // frame. 10314 // frame.
9925 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, 10315 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9926 JavaScriptFrame* frame) { 10316 JavaScriptFrame* frame) {
(...skipping 13 matching lines...) Expand all
9940 isolate, 10330 isolate,
9941 SetProperty(local_scope, 10331 SetProperty(local_scope,
9942 scope_info.parameter_name(i), 10332 scope_info.parameter_name(i),
9943 Handle<Object>(frame->GetParameter(i), isolate), 10333 Handle<Object>(frame->GetParameter(i), isolate),
9944 NONE, 10334 NONE,
9945 kNonStrictMode), 10335 kNonStrictMode),
9946 Handle<JSObject>()); 10336 Handle<JSObject>());
9947 } 10337 }
9948 10338
9949 // Second fill all stack locals. 10339 // Second fill all stack locals.
9950 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { 10340 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
9951 RETURN_IF_EMPTY_HANDLE_VALUE( 10341 RETURN_IF_EMPTY_HANDLE_VALUE(
9952 isolate, 10342 isolate,
9953 SetProperty(local_scope, 10343 SetProperty(local_scope,
9954 scope_info.stack_slot_name(i), 10344 scope_info.stack_slot_name(i),
9955 Handle<Object>(frame->GetExpression(i), isolate), 10345 Handle<Object>(frame->GetExpression(i), isolate),
9956 NONE, 10346 NONE,
9957 kNonStrictMode), 10347 kNonStrictMode),
9958 Handle<JSObject>()); 10348 Handle<JSObject>());
9959 } 10349 }
9960 10350
9961 // Third fill all context locals. 10351 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
9962 Handle<Context> frame_context(Context::cast(frame->context())); 10352 // Third fill all context locals.
9963 Handle<Context> function_context(frame_context->fcontext()); 10353 Handle<Context> frame_context(Context::cast(frame->context()));
9964 if (!CopyContextLocalsToScopeObject(isolate, 10354 Handle<Context> function_context(frame_context->declaration_context());
9965 serialized_scope_info, scope_info, 10355 if (!CopyContextLocalsToScopeObject(isolate,
9966 function_context, local_scope)) { 10356 serialized_scope_info, scope_info,
9967 return Handle<JSObject>(); 10357 function_context, local_scope)) {
9968 } 10358 return Handle<JSObject>();
10359 }
9969 10360
9970 // Finally copy any properties from the function context extension. This will 10361 // Finally copy any properties from the function context extension.
9971 // be variables introduced by eval. 10362 // These will be variables introduced by eval.
9972 if (function_context->closure() == *function) { 10363 if (function_context->closure() == *function) {
9973 if (function_context->has_extension() && 10364 if (function_context->has_extension() &&
9974 !function_context->IsGlobalContext()) { 10365 !function_context->IsGlobalContext()) {
9975 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 10366 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
9976 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); 10367 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
9977 for (int i = 0; i < keys->length(); i++) { 10368 for (int i = 0; i < keys->length(); i++) {
9978 // Names of variables introduced by eval are strings. 10369 // Names of variables introduced by eval are strings.
9979 ASSERT(keys->get(i)->IsString()); 10370 ASSERT(keys->get(i)->IsString());
9980 Handle<String> key(String::cast(keys->get(i))); 10371 Handle<String> key(String::cast(keys->get(i)));
9981 RETURN_IF_EMPTY_HANDLE_VALUE( 10372 RETURN_IF_EMPTY_HANDLE_VALUE(
9982 isolate, 10373 isolate,
9983 SetProperty(local_scope, 10374 SetProperty(local_scope,
9984 key, 10375 key,
9985 GetProperty(ext, key), 10376 GetProperty(ext, key),
9986 NONE, 10377 NONE,
9987 kNonStrictMode), 10378 kNonStrictMode),
9988 Handle<JSObject>()); 10379 Handle<JSObject>());
10380 }
9989 } 10381 }
9990 } 10382 }
9991 } 10383 }
10384
9992 return local_scope; 10385 return local_scope;
9993 } 10386 }
9994 10387
9995 10388
9996 // Create a plain JSObject which materializes the closure content for the 10389 // Create a plain JSObject which materializes the closure content for the
9997 // context. 10390 // context.
9998 static Handle<JSObject> MaterializeClosure(Isolate* isolate, 10391 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
9999 Handle<Context> context) { 10392 Handle<Context> context) {
10000 ASSERT(context->is_function_context()); 10393 ASSERT(context->IsFunctionContext());
10001 10394
10002 Handle<SharedFunctionInfo> shared(context->closure()->shared()); 10395 Handle<SharedFunctionInfo> shared(context->closure()->shared());
10003 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); 10396 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
10004 ScopeInfo<> scope_info(*serialized_scope_info); 10397 ScopeInfo<> scope_info(*serialized_scope_info);
10005 10398
10006 // Allocate and initialize a JSObject with all the content of theis function 10399 // Allocate and initialize a JSObject with all the content of theis function
10007 // closure. 10400 // closure.
10008 Handle<JSObject> closure_scope = 10401 Handle<JSObject> closure_scope =
10009 isolate->factory()->NewJSObject(isolate->object_function()); 10402 isolate->factory()->NewJSObject(isolate->object_function());
10010 10403
10011 // Check whether the arguments shadow object exists.
10012 int arguments_shadow_index =
10013 shared->scope_info()->ContextSlotIndex(
10014 isolate->heap()->arguments_shadow_symbol(), NULL);
10015 if (arguments_shadow_index >= 0) {
10016 // In this case all the arguments are available in the arguments shadow
10017 // object.
10018 Handle<JSObject> arguments_shadow(
10019 JSObject::cast(context->get(arguments_shadow_index)));
10020 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
10021 // We don't expect exception-throwing getters on the arguments shadow.
10022 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
10023 RETURN_IF_EMPTY_HANDLE_VALUE(
10024 isolate,
10025 SetProperty(closure_scope,
10026 scope_info.parameter_name(i),
10027 Handle<Object>(element, isolate),
10028 NONE,
10029 kNonStrictMode),
10030 Handle<JSObject>());
10031 }
10032 }
10033
10034 // Fill all context locals to the context extension. 10404 // Fill all context locals to the context extension.
10035 if (!CopyContextLocalsToScopeObject(isolate, 10405 if (!CopyContextLocalsToScopeObject(isolate,
10036 serialized_scope_info, scope_info, 10406 serialized_scope_info, scope_info,
10037 context, closure_scope)) { 10407 context, closure_scope)) {
10038 return Handle<JSObject>(); 10408 return Handle<JSObject>();
10039 } 10409 }
10040 10410
10041 // Finally copy any properties from the function context extension. This will 10411 // Finally copy any properties from the function context extension. This will
10042 // be variables introduced by eval. 10412 // be variables introduced by eval.
10043 if (context->has_extension()) { 10413 if (context->has_extension()) {
(...skipping 11 matching lines...) Expand all
10055 NONE, 10425 NONE,
10056 kNonStrictMode), 10426 kNonStrictMode),
10057 Handle<JSObject>()); 10427 Handle<JSObject>());
10058 } 10428 }
10059 } 10429 }
10060 10430
10061 return closure_scope; 10431 return closure_scope;
10062 } 10432 }
10063 10433
10064 10434
10435 // Create a plain JSObject which materializes the scope for the specified
10436 // catch context.
10437 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
10438 Handle<Context> context) {
10439 ASSERT(context->IsCatchContext());
10440 Handle<String> name(String::cast(context->extension()));
10441 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
10442 Handle<JSObject> catch_scope =
10443 isolate->factory()->NewJSObject(isolate->object_function());
10444 RETURN_IF_EMPTY_HANDLE_VALUE(
10445 isolate,
10446 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10447 Handle<JSObject>());
10448 return catch_scope;
10449 }
10450
10451
10065 // Iterate over the actual scopes visible from a stack frame. All scopes are 10452 // Iterate over the actual scopes visible from a stack frame. All scopes are
10066 // backed by an actual context except the local scope, which is inserted 10453 // backed by an actual context except the local scope, which is inserted
10067 // "artifically" in the context chain. 10454 // "artifically" in the context chain.
10068 class ScopeIterator { 10455 class ScopeIterator {
10069 public: 10456 public:
10070 enum ScopeType { 10457 enum ScopeType {
10071 ScopeTypeGlobal = 0, 10458 ScopeTypeGlobal = 0,
10072 ScopeTypeLocal, 10459 ScopeTypeLocal,
10073 ScopeTypeWith, 10460 ScopeTypeWith,
10074 ScopeTypeClosure, 10461 ScopeTypeClosure,
10075 // Every catch block contains an implicit with block (its parameter is
10076 // a JSContextExtensionObject) that extends current scope with a variable
10077 // holding exception object. Such with blocks are treated as scopes of their
10078 // own type.
10079 ScopeTypeCatch 10462 ScopeTypeCatch
10080 }; 10463 };
10081 10464
10082 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) 10465 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
10083 : isolate_(isolate), 10466 : isolate_(isolate),
10084 frame_(frame), 10467 frame_(frame),
10085 function_(JSFunction::cast(frame->function())), 10468 function_(JSFunction::cast(frame->function())),
10086 context_(Context::cast(frame->context())), 10469 context_(Context::cast(frame->context())),
10087 local_done_(false), 10470 local_done_(false),
10088 at_local_(false) { 10471 at_local_(false) {
10089 10472
10090 // Check whether the first scope is actually a local scope. 10473 // Check whether the first scope is actually a local scope.
10091 if (context_->IsGlobalContext()) { 10474 if (context_->IsGlobalContext()) {
10092 // If there is a stack slot for .result then this local scope has been 10475 // If there is a stack slot for .result then this local scope has been
10093 // created for evaluating top level code and it is not a real local scope. 10476 // created for evaluating top level code and it is not a real local scope.
10094 // Checking for the existence of .result seems fragile, but the scope info 10477 // Checking for the existence of .result seems fragile, but the scope info
10095 // saved with the code object does not otherwise have that information. 10478 // saved with the code object does not otherwise have that information.
10096 int index = function_->shared()->scope_info()-> 10479 int index = function_->shared()->scope_info()->
10097 StackSlotIndex(isolate_->heap()->result_symbol()); 10480 StackSlotIndex(isolate_->heap()->result_symbol());
10098 at_local_ = index < 0; 10481 at_local_ = index < 0;
10099 } else if (context_->is_function_context()) { 10482 } else if (context_->IsFunctionContext()) {
10100 at_local_ = true; 10483 at_local_ = true;
10101 } else if (context_->closure() != *function_) { 10484 } else if (context_->closure() != *function_) {
10102 // The context_ is a with block from the outer function. 10485 // The context_ is a with or catch block from the outer function.
10103 ASSERT(context_->has_extension()); 10486 ASSERT(context_->IsWithContext() || context_->IsCatchContext());
10104 at_local_ = true; 10487 at_local_ = true;
10105 } 10488 }
10106 } 10489 }
10107 10490
10108 // More scopes? 10491 // More scopes?
10109 bool Done() { return context_.is_null(); } 10492 bool Done() { return context_.is_null(); }
10110 10493
10111 // Move to the next scope. 10494 // Move to the next scope.
10112 void Next() { 10495 void Next() {
10113 // If at a local scope mark the local scope as passed. 10496 // If at a local scope mark the local scope as passed.
10114 if (at_local_) { 10497 if (at_local_) {
10115 at_local_ = false; 10498 at_local_ = false;
10116 local_done_ = true; 10499 local_done_ = true;
10117 10500
10118 // If the current context is not associated with the local scope the 10501 // If the current context is not associated with the local scope the
10119 // current context is the next real scope, so don't move to the next 10502 // current context is the next real scope, so don't move to the next
10120 // context in this case. 10503 // context in this case.
10121 if (context_->closure() != *function_) { 10504 if (context_->closure() != *function_) {
10122 return; 10505 return;
10123 } 10506 }
10124 } 10507 }
10125 10508
10126 // The global scope is always the last in the chain. 10509 // The global scope is always the last in the chain.
10127 if (context_->IsGlobalContext()) { 10510 if (context_->IsGlobalContext()) {
10128 context_ = Handle<Context>(); 10511 context_ = Handle<Context>();
10129 return; 10512 return;
10130 } 10513 }
10131 10514
10132 // Move to the next context. 10515 // Move to the next context.
10133 if (context_->is_function_context()) { 10516 context_ = Handle<Context>(context_->previous(), isolate_);
10134 context_ = Handle<Context>(Context::cast(context_->closure()->context()));
10135 } else {
10136 context_ = Handle<Context>(context_->previous());
10137 }
10138 10517
10139 // If passing the local scope indicate that the current scope is now the 10518 // If passing the local scope indicate that the current scope is now the
10140 // local scope. 10519 // local scope.
10141 if (!local_done_ && 10520 if (!local_done_ &&
10142 (context_->IsGlobalContext() || (context_->is_function_context()))) { 10521 (context_->IsGlobalContext() || context_->IsFunctionContext())) {
10143 at_local_ = true; 10522 at_local_ = true;
10144 } 10523 }
10145 } 10524 }
10146 10525
10147 // Return the type of the current scope. 10526 // Return the type of the current scope.
10148 int Type() { 10527 int Type() {
10149 if (at_local_) { 10528 if (at_local_) {
10150 return ScopeTypeLocal; 10529 return ScopeTypeLocal;
10151 } 10530 }
10152 if (context_->IsGlobalContext()) { 10531 if (context_->IsGlobalContext()) {
10153 ASSERT(context_->global()->IsGlobalObject()); 10532 ASSERT(context_->global()->IsGlobalObject());
10154 return ScopeTypeGlobal; 10533 return ScopeTypeGlobal;
10155 } 10534 }
10156 if (context_->is_function_context()) { 10535 if (context_->IsFunctionContext()) {
10157 return ScopeTypeClosure; 10536 return ScopeTypeClosure;
10158 } 10537 }
10159 ASSERT(context_->has_extension()); 10538 if (context_->IsCatchContext()) {
10160 // Current scope is either an explicit with statement or a with statement
10161 // implicitely generated for a catch block.
10162 // If the extension object here is a JSContextExtensionObject then
10163 // current with statement is one frome a catch block otherwise it's a
10164 // regular with statement.
10165 if (context_->extension()->IsJSContextExtensionObject()) {
10166 return ScopeTypeCatch; 10539 return ScopeTypeCatch;
10167 } 10540 }
10541 ASSERT(context_->IsWithContext());
10168 return ScopeTypeWith; 10542 return ScopeTypeWith;
10169 } 10543 }
10170 10544
10171 // Return the JavaScript object with the content of the current scope. 10545 // Return the JavaScript object with the content of the current scope.
10172 Handle<JSObject> ScopeObject() { 10546 Handle<JSObject> ScopeObject() {
10173 switch (Type()) { 10547 switch (Type()) {
10174 case ScopeIterator::ScopeTypeGlobal: 10548 case ScopeIterator::ScopeTypeGlobal:
10175 return Handle<JSObject>(CurrentContext()->global()); 10549 return Handle<JSObject>(CurrentContext()->global());
10176 break;
10177 case ScopeIterator::ScopeTypeLocal: 10550 case ScopeIterator::ScopeTypeLocal:
10178 // Materialize the content of the local scope into a JSObject. 10551 // Materialize the content of the local scope into a JSObject.
10179 return MaterializeLocalScope(isolate_, frame_); 10552 return MaterializeLocalScope(isolate_, frame_);
10180 break;
10181 case ScopeIterator::ScopeTypeWith: 10553 case ScopeIterator::ScopeTypeWith:
10554 // Return the with object.
10555 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10182 case ScopeIterator::ScopeTypeCatch: 10556 case ScopeIterator::ScopeTypeCatch:
10183 // Return the with object. 10557 return MaterializeCatchScope(isolate_, CurrentContext());
10184 return Handle<JSObject>(CurrentContext()->extension());
10185 break;
10186 case ScopeIterator::ScopeTypeClosure: 10558 case ScopeIterator::ScopeTypeClosure:
10187 // Materialize the content of the closure scope into a JSObject. 10559 // Materialize the content of the closure scope into a JSObject.
10188 return MaterializeClosure(isolate_, CurrentContext()); 10560 return MaterializeClosure(isolate_, CurrentContext());
10189 break;
10190 } 10561 }
10191 UNREACHABLE(); 10562 UNREACHABLE();
10192 return Handle<JSObject>(); 10563 return Handle<JSObject>();
10193 } 10564 }
10194 10565
10195 // Return the context for this scope. For the local context there might not 10566 // Return the context for this scope. For the local context there might not
10196 // be an actual context. 10567 // be an actual context.
10197 Handle<Context> CurrentContext() { 10568 Handle<Context> CurrentContext() {
10198 if (at_local_ && context_->closure() != *function_) { 10569 if (at_local_ && context_->closure() != *function_) {
10199 return Handle<Context>(); 10570 return Handle<Context>();
(...skipping 10 matching lines...) Expand all
10210 CurrentContext()->Print(); 10581 CurrentContext()->Print();
10211 break; 10582 break;
10212 10583
10213 case ScopeIterator::ScopeTypeLocal: { 10584 case ScopeIterator::ScopeTypeLocal: {
10214 PrintF("Local:\n"); 10585 PrintF("Local:\n");
10215 ScopeInfo<> scope_info(function_->shared()->scope_info()); 10586 ScopeInfo<> scope_info(function_->shared()->scope_info());
10216 scope_info.Print(); 10587 scope_info.Print();
10217 if (!CurrentContext().is_null()) { 10588 if (!CurrentContext().is_null()) {
10218 CurrentContext()->Print(); 10589 CurrentContext()->Print();
10219 if (CurrentContext()->has_extension()) { 10590 if (CurrentContext()->has_extension()) {
10220 Handle<JSObject> extension = 10591 Handle<Object> extension(CurrentContext()->extension());
10221 Handle<JSObject>(CurrentContext()->extension());
10222 if (extension->IsJSContextExtensionObject()) { 10592 if (extension->IsJSContextExtensionObject()) {
10223 extension->Print(); 10593 extension->Print();
10224 } 10594 }
10225 } 10595 }
10226 } 10596 }
10227 break; 10597 break;
10228 } 10598 }
10229 10599
10230 case ScopeIterator::ScopeTypeWith: { 10600 case ScopeIterator::ScopeTypeWith:
10231 PrintF("With:\n"); 10601 PrintF("With:\n");
10232 Handle<JSObject> extension = 10602 CurrentContext()->extension()->Print();
10233 Handle<JSObject>(CurrentContext()->extension());
10234 extension->Print();
10235 break; 10603 break;
10236 }
10237 10604
10238 case ScopeIterator::ScopeTypeCatch: { 10605 case ScopeIterator::ScopeTypeCatch:
10239 PrintF("Catch:\n"); 10606 PrintF("Catch:\n");
10240 Handle<JSObject> extension = 10607 CurrentContext()->extension()->Print();
10241 Handle<JSObject>(CurrentContext()->extension()); 10608 CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
10242 extension->Print();
10243 break; 10609 break;
10244 }
10245 10610
10246 case ScopeIterator::ScopeTypeClosure: { 10611 case ScopeIterator::ScopeTypeClosure:
10247 PrintF("Closure:\n"); 10612 PrintF("Closure:\n");
10248 CurrentContext()->Print(); 10613 CurrentContext()->Print();
10249 if (CurrentContext()->has_extension()) { 10614 if (CurrentContext()->has_extension()) {
10250 Handle<JSObject> extension = 10615 Handle<Object> extension(CurrentContext()->extension());
10251 Handle<JSObject>(CurrentContext()->extension());
10252 if (extension->IsJSContextExtensionObject()) { 10616 if (extension->IsJSContextExtensionObject()) {
10253 extension->Print(); 10617 extension->Print();
10254 } 10618 }
10255 } 10619 }
10256 break; 10620 break;
10257 }
10258 10621
10259 default: 10622 default:
10260 UNREACHABLE(); 10623 UNREACHABLE();
10261 } 10624 }
10262 PrintF("\n"); 10625 PrintF("\n");
10263 } 10626 }
10264 #endif 10627 #endif
10265 10628
10266 private: 10629 private:
10267 Isolate* isolate_; 10630 Isolate* isolate_;
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
10718 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { 11081 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
10719 HandleScope scope(isolate); 11082 HandleScope scope(isolate);
10720 ASSERT(args.length() == 0); 11083 ASSERT(args.length() == 0);
10721 isolate->debug()->ClearStepping(); 11084 isolate->debug()->ClearStepping();
10722 return isolate->heap()->undefined_value(); 11085 return isolate->heap()->undefined_value();
10723 } 11086 }
10724 11087
10725 11088
10726 // Creates a copy of the with context chain. The copy of the context chain is 11089 // Creates a copy of the with context chain. The copy of the context chain is
10727 // is linked to the function context supplied. 11090 // is linked to the function context supplied.
10728 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, 11091 static Handle<Context> CopyWithContextChain(Isolate* isolate,
10729 Handle<Context> function_context) { 11092 Handle<JSFunction> function,
10730 // At the bottom of the chain. Return the function context to link to. 11093 Handle<Context> current,
10731 if (context_chain->is_function_context()) { 11094 Handle<Context> base) {
10732 return function_context; 11095 // At the end of the chain. Return the base context to link to.
11096 if (current->IsFunctionContext() || current->IsGlobalContext()) {
11097 return base;
10733 } 11098 }
10734 11099
10735 // Recursively copy the with contexts. 11100 // Recursively copy the with and catch contexts.
10736 Handle<Context> previous(context_chain->previous()); 11101 HandleScope scope(isolate);
10737 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); 11102 Handle<Context> previous(current->previous());
10738 Handle<Context> context = CopyWithContextChain(previous, function_context); 11103 Handle<Context> new_previous =
10739 return context->GetIsolate()->factory()->NewWithContext( 11104 CopyWithContextChain(isolate, function, previous, base);
10740 context, extension, context_chain->IsCatchContext()); 11105 Handle<Context> new_current;
11106 if (current->IsCatchContext()) {
11107 Handle<String> name(String::cast(current->extension()));
11108 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11109 new_current =
11110 isolate->factory()->NewCatchContext(function,
11111 new_previous,
11112 name,
11113 thrown_object);
11114 } else {
11115 Handle<JSObject> extension(JSObject::cast(current->extension()));
11116 new_current =
11117 isolate->factory()->NewWithContext(function, new_previous, extension);
11118 }
11119 return scope.CloseAndEscape(new_current);
10741 } 11120 }
10742 11121
10743 11122
10744 // Helper function to find or create the arguments object for 11123 // Helper function to find or create the arguments object for
10745 // Runtime_DebugEvaluate. 11124 // Runtime_DebugEvaluate.
10746 static Handle<Object> GetArgumentsObject(Isolate* isolate, 11125 static Handle<Object> GetArgumentsObject(Isolate* isolate,
10747 JavaScriptFrame* frame, 11126 JavaScriptFrame* frame,
10748 Handle<JSFunction> function, 11127 Handle<JSFunction> function,
10749 Handle<SerializedScopeInfo> scope_info, 11128 Handle<SerializedScopeInfo> scope_info,
10750 const ScopeInfo<>* sinfo, 11129 const ScopeInfo<>* sinfo,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
10858 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); 11237 RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
10859 11238
10860 // Allocate a new context for the debug evaluation and set the extension 11239 // Allocate a new context for the debug evaluation and set the extension
10861 // object build. 11240 // object build.
10862 Handle<Context> context = 11241 Handle<Context> context =
10863 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, 11242 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
10864 go_between); 11243 go_between);
10865 context->set_extension(*local_scope); 11244 context->set_extension(*local_scope);
10866 // Copy any with contexts present and chain them in front of this context. 11245 // Copy any with contexts present and chain them in front of this context.
10867 Handle<Context> frame_context(Context::cast(frame->context())); 11246 Handle<Context> frame_context(Context::cast(frame->context()));
10868 Handle<Context> function_context(frame_context->fcontext()); 11247 Handle<Context> function_context(frame_context->declaration_context());
10869 context = CopyWithContextChain(frame_context, context); 11248 context = CopyWithContextChain(isolate, go_between, frame_context, context);
10870 11249
10871 if (additional_context->IsJSObject()) { 11250 if (additional_context->IsJSObject()) {
10872 context = isolate->factory()->NewWithContext(context, 11251 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
10873 Handle<JSObject>::cast(additional_context), false); 11252 context =
11253 isolate->factory()->NewWithContext(go_between, context, extension);
10874 } 11254 }
10875 11255
10876 // Wrap the evaluation statement in a new function compiled in the newly 11256 // Wrap the evaluation statement in a new function compiled in the newly
10877 // created context. The function has one parameter which has to be called 11257 // created context. The function has one parameter which has to be called
10878 // 'arguments'. This it to have access to what would have been 'arguments' in 11258 // 'arguments'. This it to have access to what would have been 'arguments' in
10879 // the function being debugged. 11259 // the function being debugged.
10880 // function(arguments,__source__) {return eval(__source__);} 11260 // function(arguments,__source__) {return eval(__source__);}
10881 11261
10882 Handle<String> function_source = 11262 Handle<String> function_source =
10883 isolate->factory()->NewStringFromAscii( 11263 isolate->factory()->NewStringFromAscii(
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
11620 return LiveObjectList::Capture(); 12000 return LiveObjectList::Capture();
11621 #else 12001 #else
11622 return isolate->heap()->undefined_value(); 12002 return isolate->heap()->undefined_value();
11623 #endif 12003 #endif
11624 } 12004 }
11625 12005
11626 12006
11627 // Deletes the specified live object list. 12007 // Deletes the specified live object list.
11628 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) { 12008 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
11629 #ifdef LIVE_OBJECT_LIST 12009 #ifdef LIVE_OBJECT_LIST
11630 CONVERT_SMI_CHECKED(id, args[0]); 12010 CONVERT_SMI_ARG_CHECKED(id, 0);
11631 bool success = LiveObjectList::Delete(id); 12011 bool success = LiveObjectList::Delete(id);
11632 return success ? isolate->heap()->true_value() : 12012 return success ? isolate->heap()->true_value() :
11633 isolate->heap()->false_value(); 12013 isolate->heap()->false_value();
11634 #else 12014 #else
11635 return isolate->heap()->undefined_value(); 12015 return isolate->heap()->undefined_value();
11636 #endif 12016 #endif
11637 } 12017 }
11638 12018
11639 12019
11640 // Generates the response to a debugger request for a dump of the objects 12020 // Generates the response to a debugger request for a dump of the objects
11641 // contained in the difference between the captured live object lists 12021 // contained in the difference between the captured live object lists
11642 // specified by id1 and id2. 12022 // specified by id1 and id2.
11643 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be 12023 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
11644 // dumped. 12024 // dumped.
11645 RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) { 12025 RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
11646 #ifdef LIVE_OBJECT_LIST 12026 #ifdef LIVE_OBJECT_LIST
11647 HandleScope scope; 12027 HandleScope scope;
11648 CONVERT_SMI_CHECKED(id1, args[0]); 12028 CONVERT_SMI_ARG_CHECKED(id1, 0);
11649 CONVERT_SMI_CHECKED(id2, args[1]); 12029 CONVERT_SMI_ARG_CHECKED(id2, 1);
11650 CONVERT_SMI_CHECKED(start, args[2]); 12030 CONVERT_SMI_ARG_CHECKED(start, 2);
11651 CONVERT_SMI_CHECKED(count, args[3]); 12031 CONVERT_SMI_ARG_CHECKED(count, 3);
11652 CONVERT_ARG_CHECKED(JSObject, filter_obj, 4); 12032 CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
11653 EnterDebugger enter_debugger; 12033 EnterDebugger enter_debugger;
11654 return LiveObjectList::Dump(id1, id2, start, count, filter_obj); 12034 return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
11655 #else 12035 #else
11656 return isolate->heap()->undefined_value(); 12036 return isolate->heap()->undefined_value();
11657 #endif 12037 #endif
11658 } 12038 }
11659 12039
11660 12040
11661 // Gets the specified object as requested by the debugger. 12041 // Gets the specified object as requested by the debugger.
11662 // This is only used for obj ids shown in live object lists. 12042 // This is only used for obj ids shown in live object lists.
11663 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) { 12043 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
11664 #ifdef LIVE_OBJECT_LIST 12044 #ifdef LIVE_OBJECT_LIST
11665 CONVERT_SMI_CHECKED(obj_id, args[0]); 12045 CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11666 Object* result = LiveObjectList::GetObj(obj_id); 12046 Object* result = LiveObjectList::GetObj(obj_id);
11667 return result; 12047 return result;
11668 #else 12048 #else
11669 return isolate->heap()->undefined_value(); 12049 return isolate->heap()->undefined_value();
11670 #endif 12050 #endif
11671 } 12051 }
11672 12052
11673 12053
11674 // Gets the obj id for the specified address if valid. 12054 // Gets the obj id for the specified address if valid.
11675 // This is only used for obj ids shown in live object lists. 12055 // This is only used for obj ids shown in live object lists.
11676 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) { 12056 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
11677 #ifdef LIVE_OBJECT_LIST 12057 #ifdef LIVE_OBJECT_LIST
11678 HandleScope scope; 12058 HandleScope scope;
11679 CONVERT_ARG_CHECKED(String, address, 0); 12059 CONVERT_ARG_CHECKED(String, address, 0);
11680 Object* result = LiveObjectList::GetObjId(address); 12060 Object* result = LiveObjectList::GetObjId(address);
11681 return result; 12061 return result;
11682 #else 12062 #else
11683 return isolate->heap()->undefined_value(); 12063 return isolate->heap()->undefined_value();
11684 #endif 12064 #endif
11685 } 12065 }
11686 12066
11687 12067
11688 // Gets the retainers that references the specified object alive. 12068 // Gets the retainers that references the specified object alive.
11689 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) { 12069 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11690 #ifdef LIVE_OBJECT_LIST 12070 #ifdef LIVE_OBJECT_LIST
11691 HandleScope scope; 12071 HandleScope scope;
11692 CONVERT_SMI_CHECKED(obj_id, args[0]); 12072 CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11693 RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject()); 12073 RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
11694 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean()); 12074 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
11695 RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi()); 12075 RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
11696 RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi()); 12076 RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi());
11697 CONVERT_ARG_CHECKED(JSObject, filter_obj, 5); 12077 CONVERT_ARG_CHECKED(JSObject, filter_obj, 5);
11698 12078
11699 Handle<JSObject> instance_filter; 12079 Handle<JSObject> instance_filter;
11700 if (args[1]->IsJSObject()) { 12080 if (args[1]->IsJSObject()) {
11701 instance_filter = args.at<JSObject>(1); 12081 instance_filter = args.at<JSObject>(1);
11702 } 12082 }
11703 bool verbose = false; 12083 bool verbose = false;
11704 if (args[2]->IsBoolean()) { 12084 if (args[2]->IsBoolean()) {
11705 verbose = args[2]->IsTrue(); 12085 verbose = args[2]->IsTrue();
11706 } 12086 }
11707 int start = 0; 12087 int start = 0;
11708 if (args[3]->IsSmi()) { 12088 if (args[3]->IsSmi()) {
11709 start = Smi::cast(args[3])->value(); 12089 start = args.smi_at(3);
11710 } 12090 }
11711 int limit = Smi::kMaxValue; 12091 int limit = Smi::kMaxValue;
11712 if (args[4]->IsSmi()) { 12092 if (args[4]->IsSmi()) {
11713 limit = Smi::cast(args[4])->value(); 12093 limit = args.smi_at(4);
11714 } 12094 }
11715 12095
11716 return LiveObjectList::GetObjRetainers(obj_id, 12096 return LiveObjectList::GetObjRetainers(obj_id,
11717 instance_filter, 12097 instance_filter,
11718 verbose, 12098 verbose,
11719 start, 12099 start,
11720 limit, 12100 limit,
11721 filter_obj); 12101 filter_obj);
11722 #else 12102 #else
11723 return isolate->heap()->undefined_value(); 12103 return isolate->heap()->undefined_value();
11724 #endif 12104 #endif
11725 } 12105 }
11726 12106
11727 12107
11728 // Gets the reference path between 2 objects. 12108 // Gets the reference path between 2 objects.
11729 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) { 12109 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
11730 #ifdef LIVE_OBJECT_LIST 12110 #ifdef LIVE_OBJECT_LIST
11731 HandleScope scope; 12111 HandleScope scope;
11732 CONVERT_SMI_CHECKED(obj_id1, args[0]); 12112 CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
11733 CONVERT_SMI_CHECKED(obj_id2, args[1]); 12113 CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
11734 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject()); 12114 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
11735 12115
11736 Handle<JSObject> instance_filter; 12116 Handle<JSObject> instance_filter;
11737 if (args[2]->IsJSObject()) { 12117 if (args[2]->IsJSObject()) {
11738 instance_filter = args.at<JSObject>(2); 12118 instance_filter = args.at<JSObject>(2);
11739 } 12119 }
11740 12120
11741 Object* result = 12121 Object* result =
11742 LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter); 12122 LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter);
11743 return result; 12123 return result;
11744 #else 12124 #else
11745 return isolate->heap()->undefined_value(); 12125 return isolate->heap()->undefined_value();
11746 #endif 12126 #endif
11747 } 12127 }
11748 12128
11749 12129
11750 // Generates the response to a debugger request for a list of all 12130 // Generates the response to a debugger request for a list of all
11751 // previously captured live object lists. 12131 // previously captured live object lists.
11752 RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) { 12132 RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
11753 #ifdef LIVE_OBJECT_LIST 12133 #ifdef LIVE_OBJECT_LIST
11754 CONVERT_SMI_CHECKED(start, args[0]); 12134 CONVERT_SMI_ARG_CHECKED(start, 0);
11755 CONVERT_SMI_CHECKED(count, args[1]); 12135 CONVERT_SMI_ARG_CHECKED(count, 1);
11756 return LiveObjectList::Info(start, count); 12136 return LiveObjectList::Info(start, count);
11757 #else 12137 #else
11758 return isolate->heap()->undefined_value(); 12138 return isolate->heap()->undefined_value();
11759 #endif 12139 #endif
11760 } 12140 }
11761 12141
11762 12142
11763 // Gets a dump of the specified object as requested by the debugger. 12143 // Gets a dump of the specified object as requested by the debugger.
11764 // This is only used for obj ids shown in live object lists. 12144 // This is only used for obj ids shown in live object lists.
11765 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) { 12145 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
11766 #ifdef LIVE_OBJECT_LIST 12146 #ifdef LIVE_OBJECT_LIST
11767 HandleScope scope; 12147 HandleScope scope;
11768 CONVERT_SMI_CHECKED(obj_id, args[0]); 12148 CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11769 Object* result = LiveObjectList::PrintObj(obj_id); 12149 Object* result = LiveObjectList::PrintObj(obj_id);
11770 return result; 12150 return result;
11771 #else 12151 #else
11772 return isolate->heap()->undefined_value(); 12152 return isolate->heap()->undefined_value();
11773 #endif 12153 #endif
11774 } 12154 }
11775 12155
11776 12156
11777 // Resets and releases all previously captured live object lists. 12157 // Resets and releases all previously captured live object lists.
11778 RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) { 12158 RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) {
11779 #ifdef LIVE_OBJECT_LIST 12159 #ifdef LIVE_OBJECT_LIST
11780 LiveObjectList::Reset(); 12160 LiveObjectList::Reset();
11781 return isolate->heap()->undefined_value(); 12161 return isolate->heap()->undefined_value();
11782 #else 12162 #else
11783 return isolate->heap()->undefined_value(); 12163 return isolate->heap()->undefined_value();
11784 #endif 12164 #endif
11785 } 12165 }
11786 12166
11787 12167
11788 // Generates the response to a debugger request for a summary of the types 12168 // Generates the response to a debugger request for a summary of the types
11789 // of objects in the difference between the captured live object lists 12169 // of objects in the difference between the captured live object lists
11790 // specified by id1 and id2. 12170 // specified by id1 and id2.
11791 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be 12171 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
11792 // summarized. 12172 // summarized.
11793 RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) { 12173 RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
11794 #ifdef LIVE_OBJECT_LIST 12174 #ifdef LIVE_OBJECT_LIST
11795 HandleScope scope; 12175 HandleScope scope;
11796 CONVERT_SMI_CHECKED(id1, args[0]); 12176 CONVERT_SMI_ARG_CHECKED(id1, 0);
11797 CONVERT_SMI_CHECKED(id2, args[1]); 12177 CONVERT_SMI_ARG_CHECKED(id2, 1);
11798 CONVERT_ARG_CHECKED(JSObject, filter_obj, 2); 12178 CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
11799 12179
11800 EnterDebugger enter_debugger; 12180 EnterDebugger enter_debugger;
11801 return LiveObjectList::Summarize(id1, id2, filter_obj); 12181 return LiveObjectList::Summarize(id1, id2, filter_obj);
11802 #else 12182 #else
11803 return isolate->heap()->undefined_value(); 12183 return isolate->heap()->undefined_value();
11804 #endif 12184 #endif
11805 } 12185 }
11806 12186
11807 #endif // ENABLE_DEBUGGER_SUPPORT 12187 #endif // ENABLE_DEBUGGER_SUPPORT
11808 12188
11809 12189
11810 #ifdef ENABLE_LOGGING_AND_PROFILING 12190 #ifdef ENABLE_LOGGING_AND_PROFILING
11811 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) { 12191 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
11812 NoHandleAllocation ha; 12192 NoHandleAllocation ha;
11813 ASSERT(args.length() == 2); 12193 v8::V8::ResumeProfiler();
11814
11815 CONVERT_CHECKED(Smi, smi_modules, args[0]);
11816 CONVERT_CHECKED(Smi, smi_tag, args[1]);
11817 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
11818 return isolate->heap()->undefined_value(); 12194 return isolate->heap()->undefined_value();
11819 } 12195 }
11820 12196
11821 12197
11822 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) { 12198 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) {
11823 NoHandleAllocation ha; 12199 NoHandleAllocation ha;
11824 ASSERT(args.length() == 2); 12200 v8::V8::PauseProfiler();
11825
11826 CONVERT_CHECKED(Smi, smi_modules, args[0]);
11827 CONVERT_CHECKED(Smi, smi_tag, args[1]);
11828 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
11829 return isolate->heap()->undefined_value(); 12201 return isolate->heap()->undefined_value();
11830 } 12202 }
11831 12203
11832 #endif // ENABLE_LOGGING_AND_PROFILING 12204 #endif // ENABLE_LOGGING_AND_PROFILING
11833 12205
11834 // Finds the script object from the script data. NOTE: This operation uses 12206 // Finds the script object from the script data. NOTE: This operation uses
11835 // heap traversal to find the function generated for the source position 12207 // heap traversal to find the function generated for the source position
11836 // for the requested break point. For lazily compiled functions several heap 12208 // for the requested break point. For lazily compiled functions several heap
11837 // traversals might be required rendering this operation as a rather slow 12209 // traversals might be required rendering this operation as a rather slow
11838 // operation. However for setting break points which is normally done through 12210 // operation. However for setting break points which is normally done through
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
11978 12350
11979 const char* version_string = v8::V8::GetVersion(); 12351 const char* version_string = v8::V8::GetVersion();
11980 12352
11981 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string), 12353 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string),
11982 NOT_TENURED); 12354 NOT_TENURED);
11983 } 12355 }
11984 12356
11985 12357
11986 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) { 12358 RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
11987 ASSERT(args.length() == 2); 12359 ASSERT(args.length() == 2);
11988 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + 12360 OS::PrintError("abort: %s\n",
11989 Smi::cast(args[1])->value()); 12361 reinterpret_cast<char*>(args[0]) + args.smi_at(1));
11990 isolate->PrintStack(); 12362 isolate->PrintStack();
11991 OS::Abort(); 12363 OS::Abort();
11992 UNREACHABLE(); 12364 UNREACHABLE();
11993 return NULL; 12365 return NULL;
11994 } 12366 }
11995 12367
11996 12368
11997 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) { 12369 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) {
11998 // This is only called from codegen, so checks might be more lax. 12370 // This is only called from codegen, so checks might be more lax.
11999 CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]); 12371 CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
12181 return isolate->heap()->undefined_value(); 12553 return isolate->heap()->undefined_value();
12182 } 12554 }
12183 12555
12184 12556
12185 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { 12557 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
12186 UNREACHABLE(); // implemented as macro in the parser 12558 UNREACHABLE(); // implemented as macro in the parser
12187 return NULL; 12559 return NULL;
12188 } 12560 }
12189 12561
12190 12562
12563 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
12564 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
12565 CONVERT_CHECKED(JSObject, obj, args[0]); \
12566 return isolate->heap()->ToBoolean(obj->Has##Name()); \
12567 }
12568
12569 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
12570 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
12571 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
12572 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
12573 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
12574 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
12575 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
12576 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
12577 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
12578 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
12579 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
12580 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
12581 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
12582
12583 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
12584
12191 // ---------------------------------------------------------------------------- 12585 // ----------------------------------------------------------------------------
12192 // Implementation of Runtime 12586 // Implementation of Runtime
12193 12587
12194 #define F(name, number_of_args, result_size) \ 12588 #define F(name, number_of_args, result_size) \
12195 { Runtime::k##name, Runtime::RUNTIME, #name, \ 12589 { Runtime::k##name, Runtime::RUNTIME, #name, \
12196 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, 12590 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
12197 12591
12198 12592
12199 #define I(name, number_of_args, result_size) \ 12593 #define I(name, number_of_args, result_size) \
12200 { Runtime::kInline##name, Runtime::INLINE, \ 12594 { Runtime::kInline##name, Runtime::INLINE, \
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
12264 } else { 12658 } else {
12265 // Handle last resort GC and make sure to allow future allocations 12659 // Handle last resort GC and make sure to allow future allocations
12266 // to grow the heap without causing GCs (if possible). 12660 // to grow the heap without causing GCs (if possible).
12267 isolate->counters()->gc_last_resort_from_js()->Increment(); 12661 isolate->counters()->gc_last_resort_from_js()->Increment();
12268 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 12662 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
12269 } 12663 }
12270 } 12664 }
12271 12665
12272 12666
12273 } } // namespace v8::internal 12667 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698