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

Side by Side Diff: src/runtime.cc

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); 568 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
569 AllocationSiteUsageContext usage_context(isolate, site, true); 569 AllocationSiteUsageContext usage_context(isolate, site, true);
570 usage_context.EnterNewScope(); 570 usage_context.EnterNewScope();
571 Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context); 571 Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context);
572 usage_context.ExitScope(site, boilerplate); 572 usage_context.ExitScope(site, boilerplate);
573 RETURN_IF_EMPTY_HANDLE(isolate, copy); 573 RETURN_IF_EMPTY_HANDLE(isolate, copy);
574 return *copy; 574 return *copy;
575 } 575 }
576 576
577 577
578 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
579 HandleScope scope(isolate);
580 ASSERT(args.length() == 3);
581 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
582 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
583 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
584
585 Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
586 literals_index, elements);
587 RETURN_IF_EMPTY_HANDLE(isolate, site);
588
589 JSObject* boilerplate = JSObject::cast(site->transition_info());
590 if (boilerplate->elements()->map() ==
591 isolate->heap()->fixed_cow_array_map()) {
592 isolate->counters()->cow_arrays_created_runtime()->Increment();
593 }
594
595 if (AllocationSite::GetMode(boilerplate->GetElementsKind()) ==
596 TRACK_ALLOCATION_SITE) {
597 return isolate->heap()->CopyJSObject(boilerplate, *site);
598 }
599
600 return isolate->heap()->CopyJSObject(boilerplate);
601 }
602
603
604 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) { 578 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
605 HandleScope scope(isolate); 579 HandleScope scope(isolate);
606 ASSERT(args.length() == 1); 580 ASSERT(args.length() == 1);
607 Handle<Object> name(args[0], isolate); 581 Handle<Object> name(args[0], isolate);
608 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); 582 RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
609 Symbol* symbol; 583 Symbol* symbol;
610 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); 584 MaybeObject* maybe = isolate->heap()->AllocateSymbol();
611 if (!maybe->To(&symbol)) return maybe; 585 if (!maybe->To(&symbol)) return maybe;
612 if (name->IsString()) symbol->set_name(*name); 586 if (name->IsString()) symbol->set_name(*name);
613 return symbol; 587 return symbol;
588 }
589
590
591 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreatePrivateSymbol) {
592 HandleScope scope(isolate);
593 ASSERT(args.length() == 1);
594 Handle<Object> name(args[0], isolate);
595 RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
596 Symbol* symbol;
597 MaybeObject* maybe = isolate->heap()->AllocatePrivateSymbol();
598 if (!maybe->To(&symbol)) return maybe;
599 if (name->IsString()) symbol->set_name(*name);
600 return symbol;
614 } 601 }
615 602
616 603
617 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) { 604 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolName) {
618 SealHandleScope shs(isolate); 605 SealHandleScope shs(isolate);
619 ASSERT(args.length() == 1); 606 ASSERT(args.length() == 1);
620 CONVERT_ARG_CHECKED(Symbol, symbol, 0); 607 CONVERT_ARG_CHECKED(Symbol, symbol, 0);
621 return symbol->name(); 608 return symbol->name();
622 } 609 }
623 610
624 611
612 RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
613 SealHandleScope shs(isolate);
614 ASSERT(args.length() == 1);
615 CONVERT_ARG_CHECKED(Symbol, symbol, 0);
616 return isolate->heap()->ToBoolean(symbol->is_private());
617 }
618
619
625 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { 620 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
626 SealHandleScope shs(isolate); 621 SealHandleScope shs(isolate);
627 ASSERT(args.length() == 2); 622 ASSERT(args.length() == 2);
628 CONVERT_ARG_CHECKED(JSReceiver, handler, 0); 623 CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
629 Object* prototype = args[1]; 624 Object* prototype = args[1];
630 Object* used_prototype = 625 Object* used_prototype =
631 prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); 626 prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
632 return isolate->heap()->AllocateJSProxy(handler, used_prototype); 627 return isolate->heap()->AllocateJSProxy(handler, used_prototype);
633 } 628 }
634 629
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 return *holder; 1401 return *holder;
1407 } 1402 }
1408 1403
1409 1404
1410 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) { 1405 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
1411 HandleScope scope(isolate); 1406 HandleScope scope(isolate);
1412 ASSERT(args.length() == 2); 1407 ASSERT(args.length() == 2);
1413 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1408 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1414 Handle<Object> key(args[1], isolate); 1409 Handle<Object> key(args[1], isolate);
1415 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); 1410 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1416 table = ObjectHashSetAdd(table, key); 1411 table = ObjectHashSet::Add(table, key);
1417 holder->set_table(*table); 1412 holder->set_table(*table);
1418 return isolate->heap()->undefined_value(); 1413 return isolate->heap()->undefined_value();
1419 } 1414 }
1420 1415
1421 1416
1422 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) { 1417 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
1423 HandleScope scope(isolate); 1418 HandleScope scope(isolate);
1424 ASSERT(args.length() == 2); 1419 ASSERT(args.length() == 2);
1425 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1420 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1426 Handle<Object> key(args[1], isolate); 1421 Handle<Object> key(args[1], isolate);
1427 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); 1422 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1428 return isolate->heap()->ToBoolean(table->Contains(*key)); 1423 return isolate->heap()->ToBoolean(table->Contains(*key));
1429 } 1424 }
1430 1425
1431 1426
1432 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) { 1427 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
1433 HandleScope scope(isolate); 1428 HandleScope scope(isolate);
1434 ASSERT(args.length() == 2); 1429 ASSERT(args.length() == 2);
1435 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1430 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1436 Handle<Object> key(args[1], isolate); 1431 Handle<Object> key(args[1], isolate);
1437 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); 1432 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
1438 table = ObjectHashSetRemove(table, key); 1433 table = ObjectHashSet::Remove(table, key);
1439 holder->set_table(*table); 1434 holder->set_table(*table);
1440 return isolate->heap()->undefined_value(); 1435 return isolate->heap()->undefined_value();
1441 } 1436 }
1442 1437
1443 1438
1444 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) { 1439 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
1445 HandleScope scope(isolate); 1440 HandleScope scope(isolate);
1446 ASSERT(args.length() == 1); 1441 ASSERT(args.length() == 1);
1447 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1442 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1448 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); 1443 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 1478
1484 1479
1485 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) { 1480 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
1486 HandleScope scope(isolate); 1481 HandleScope scope(isolate);
1487 ASSERT(args.length() == 2); 1482 ASSERT(args.length() == 2);
1488 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 1483 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1489 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 1484 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1490 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); 1485 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1491 Handle<Object> lookup(table->Lookup(*key), isolate); 1486 Handle<Object> lookup(table->Lookup(*key), isolate);
1492 Handle<ObjectHashTable> new_table = 1487 Handle<ObjectHashTable> new_table =
1493 PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value()); 1488 ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
1494 holder->set_table(*new_table); 1489 holder->set_table(*new_table);
1495 return isolate->heap()->ToBoolean(!lookup->IsTheHole()); 1490 return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1496 } 1491 }
1497 1492
1498 1493
1499 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) { 1494 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
1500 HandleScope scope(isolate); 1495 HandleScope scope(isolate);
1501 ASSERT(args.length() == 3); 1496 ASSERT(args.length() == 3);
1502 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 1497 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1503 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 1498 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1504 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 1499 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1505 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); 1500 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1506 Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value); 1501 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1507 holder->set_table(*new_table); 1502 holder->set_table(*new_table);
1508 return isolate->heap()->undefined_value(); 1503 return isolate->heap()->undefined_value();
1509 } 1504 }
1510 1505
1511 1506
1512 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) { 1507 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
1513 HandleScope scope(isolate); 1508 HandleScope scope(isolate);
1514 ASSERT(args.length() == 1); 1509 ASSERT(args.length() == 1);
1515 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); 1510 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1516 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); 1511 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 1557
1563 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) { 1558 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
1564 HandleScope scope(isolate); 1559 HandleScope scope(isolate);
1565 ASSERT(args.length() == 2); 1560 ASSERT(args.length() == 2);
1566 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 1561 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1567 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 1562 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1568 Handle<ObjectHashTable> table(ObjectHashTable::cast( 1563 Handle<ObjectHashTable> table(ObjectHashTable::cast(
1569 weak_collection->table())); 1564 weak_collection->table()));
1570 Handle<Object> lookup(table->Lookup(*key), isolate); 1565 Handle<Object> lookup(table->Lookup(*key), isolate);
1571 Handle<ObjectHashTable> new_table = 1566 Handle<ObjectHashTable> new_table =
1572 PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value()); 1567 ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
1573 weak_collection->set_table(*new_table); 1568 weak_collection->set_table(*new_table);
1574 return isolate->heap()->ToBoolean(!lookup->IsTheHole()); 1569 return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1575 } 1570 }
1576 1571
1577 1572
1578 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) { 1573 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
1579 HandleScope scope(isolate); 1574 HandleScope scope(isolate);
1580 ASSERT(args.length() == 3); 1575 ASSERT(args.length() == 3);
1581 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); 1576 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1582 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); 1577 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1583 Handle<Object> value(args[2], isolate); 1578 Handle<Object> value(args[2], isolate);
1584 Handle<ObjectHashTable> table( 1579 Handle<ObjectHashTable> table(
1585 ObjectHashTable::cast(weak_collection->table())); 1580 ObjectHashTable::cast(weak_collection->table()));
1586 Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value); 1581 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1587 weak_collection->set_table(*new_table); 1582 weak_collection->set_table(*new_table);
1588 return isolate->heap()->undefined_value(); 1583 return isolate->heap()->undefined_value();
1589 } 1584 }
1590 1585
1591 1586
1592 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) { 1587 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
1593 SealHandleScope shs(isolate); 1588 SealHandleScope shs(isolate);
1594 ASSERT(args.length() == 1); 1589 ASSERT(args.length() == 1);
1595 Object* obj = args[0]; 1590 Object* obj = args[0];
1596 if (!obj->IsJSObject()) return isolate->heap()->null_value(); 1591 if (!obj->IsJSObject()) return isolate->heap()->null_value();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 if (FLAG_harmony_observation && obj->map()->is_observed()) { 1634 if (FLAG_harmony_observation && obj->map()->is_observed()) {
1640 Handle<Object> old_value( 1635 Handle<Object> old_value(
1641 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate); 1636 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
1642 1637
1643 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true); 1638 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
1644 RETURN_IF_EMPTY_HANDLE(isolate, result); 1639 RETURN_IF_EMPTY_HANDLE(isolate, result);
1645 1640
1646 Handle<Object> new_value( 1641 Handle<Object> new_value(
1647 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate); 1642 GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
1648 if (!new_value->SameValue(*old_value)) { 1643 if (!new_value->SameValue(*old_value)) {
1649 JSObject::EnqueueChangeRecord(obj, "prototype", 1644 JSObject::EnqueueChangeRecord(obj, "setPrototype",
1650 isolate->factory()->proto_string(), 1645 isolate->factory()->proto_string(),
1651 old_value); 1646 old_value);
1652 } 1647 }
1653 return *result; 1648 return *result;
1654 } 1649 }
1655 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true); 1650 Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
1656 RETURN_IF_EMPTY_HANDLE(isolate, result); 1651 RETURN_IF_EMPTY_HANDLE(isolate, result);
1657 return *result; 1652 return *result;
1658 } 1653 }
1659 1654
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2993 Handle<Map>(func->initial_map())); 2988 Handle<Map>(func->initial_map()));
2994 new_initial_map->set_unused_property_fields(num); 2989 new_initial_map->set_unused_property_fields(num);
2995 func->set_initial_map(*new_initial_map); 2990 func->set_initial_map(*new_initial_map);
2996 } 2991 }
2997 } 2992 }
2998 return isolate->heap()->undefined_value(); 2993 return isolate->heap()->undefined_value();
2999 } 2994 }
3000 2995
3001 2996
3002 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { 2997 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) {
3003 SealHandleScope shs(isolate); 2998 HandleScope scope(isolate);
3004 ASSERT(args.length() == 0); 2999 ASSERT(args.length() == 0);
3005 3000
3006 JavaScriptFrameIterator it(isolate); 3001 JavaScriptFrameIterator it(isolate);
3007 JavaScriptFrame* frame = it.frame(); 3002 JavaScriptFrame* frame = it.frame();
3008 JSFunction* function = frame->function(); 3003 Handle<JSFunction> function(frame->function());
3009 RUNTIME_ASSERT(function->shared()->is_generator()); 3004 RUNTIME_ASSERT(function->shared()->is_generator());
3010 3005
3011 JSGeneratorObject* generator; 3006 Handle<JSGeneratorObject> generator;
3012 if (frame->IsConstructor()) { 3007 if (frame->IsConstructor()) {
3013 generator = JSGeneratorObject::cast(frame->receiver()); 3008 generator = handle(JSGeneratorObject::cast(frame->receiver()));
3014 } else { 3009 } else {
3015 MaybeObject* maybe_generator = 3010 generator = isolate->factory()->NewJSGeneratorObject(function);
3016 isolate->heap()->AllocateJSGeneratorObject(function);
3017 if (!maybe_generator->To(&generator)) return maybe_generator;
3018 } 3011 }
3019 generator->set_function(function); 3012 generator->set_function(*function);
3020 generator->set_context(Context::cast(frame->context())); 3013 generator->set_context(Context::cast(frame->context()));
3021 generator->set_receiver(frame->receiver()); 3014 generator->set_receiver(frame->receiver());
3022 generator->set_continuation(0); 3015 generator->set_continuation(0);
3023 generator->set_operand_stack(isolate->heap()->empty_fixed_array()); 3016 generator->set_operand_stack(isolate->heap()->empty_fixed_array());
3024 generator->set_stack_handler_index(-1); 3017 generator->set_stack_handler_index(-1);
3025 3018
3026 return generator; 3019 return *generator;
3027 } 3020 }
3028 3021
3029 3022
3030 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { 3023 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
3031 SealHandleScope shs(isolate); 3024 SealHandleScope shs(isolate);
3032 ASSERT(args.length() == 1); 3025 ASSERT(args.length() == 1);
3033 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); 3026 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
3034 3027
3035 JavaScriptFrameIterator stack_iterator(isolate); 3028 JavaScriptFrameIterator stack_iterator(isolate);
3036 JavaScriptFrame* frame = stack_iterator.frame(); 3029 JavaScriptFrame* frame = stack_iterator.frame();
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 } 4804 }
4812 4805
4813 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { 4806 if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
4814 return object->GetPrototype(isolate)->GetElement(isolate, index); 4807 return object->GetPrototype(isolate)->GetElement(isolate, index);
4815 } 4808 }
4816 4809
4817 return object->GetElement(isolate, index); 4810 return object->GetElement(isolate, index);
4818 } 4811 }
4819 4812
4820 4813
4814 static Handle<Name> ToName(Isolate* isolate, Handle<Object> key) {
4815 if (key->IsName()) {
4816 return Handle<Name>::cast(key);
4817 } else {
4818 bool has_pending_exception = false;
4819 Handle<Object> converted =
4820 Execution::ToString(isolate, key, &has_pending_exception);
4821 if (has_pending_exception) return Handle<Name>();
4822 return Handle<Name>::cast(converted);
4823 }
4824 }
4825
4826
4821 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, 4827 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
4822 Handle<JSReceiver> object, 4828 Handle<JSReceiver> object,
4823 Handle<Object> key) { 4829 Handle<Object> key) {
4824 HandleScope scope(isolate); 4830 HandleScope scope(isolate);
4825 4831
4826 // Check if the given key is an array index. 4832 // Check if the given key is an array index.
4827 uint32_t index; 4833 uint32_t index;
4828 if (key->ToArrayIndex(&index)) { 4834 if (key->ToArrayIndex(&index)) {
4829 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index)); 4835 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
4830 } 4836 }
4831 4837
4832 // Convert the key to a name - possibly by calling back into JavaScript. 4838 // Convert the key to a name - possibly by calling back into JavaScript.
4833 Handle<Name> name; 4839 Handle<Name> name = ToName(isolate, key);
4834 if (key->IsName()) { 4840 RETURN_IF_EMPTY_HANDLE(isolate, name);
4835 name = Handle<Name>::cast(key);
4836 } else {
4837 bool has_pending_exception = false;
4838 Handle<Object> converted =
4839 Execution::ToString(isolate, key, &has_pending_exception);
4840 if (has_pending_exception) return Failure::Exception();
4841 name = Handle<Name>::cast(converted);
4842 }
4843 4841
4844 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name)); 4842 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
4845 } 4843 }
4846 4844
4847 MaybeObject* Runtime::GetObjectPropertyOrFail( 4845 MaybeObject* Runtime::GetObjectPropertyOrFail(
4848 Isolate* isolate, 4846 Isolate* isolate,
4849 Handle<Object> object, 4847 Handle<Object> object,
4850 Handle<Object> key) { 4848 Handle<Object> key) {
4851 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, 4849 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
4852 GetObjectProperty(isolate, object, key)); 4850 GetObjectProperty(isolate, object, key));
(...skipping 12 matching lines...) Expand all
4865 return isolate->Throw(*error); 4863 return isolate->Throw(*error);
4866 } 4864 }
4867 4865
4868 // Check if the given key is an array index. 4866 // Check if the given key is an array index.
4869 uint32_t index; 4867 uint32_t index;
4870 if (key->ToArrayIndex(&index)) { 4868 if (key->ToArrayIndex(&index)) {
4871 return GetElementOrCharAt(isolate, object, index); 4869 return GetElementOrCharAt(isolate, object, index);
4872 } 4870 }
4873 4871
4874 // Convert the key to a name - possibly by calling back into JavaScript. 4872 // Convert the key to a name - possibly by calling back into JavaScript.
4875 Handle<Name> name; 4873 Handle<Name> name = ToName(isolate, key);
4876 if (key->IsName()) { 4874 RETURN_IF_EMPTY_HANDLE(isolate, name);
4877 name = Handle<Name>::cast(key);
4878 } else {
4879 bool has_pending_exception = false;
4880 Handle<Object> converted =
4881 Execution::ToString(isolate, key, &has_pending_exception);
4882 if (has_pending_exception) return Failure::Exception();
4883 name = Handle<Name>::cast(converted);
4884 }
4885 4875
4886 // Check if the name is trivially convertible to an index and get 4876 // Check if the name is trivially convertible to an index and get
4887 // the element if so. 4877 // the element if so.
4888 if (name->AsArrayIndex(&index)) { 4878 if (name->AsArrayIndex(&index)) {
4889 return GetElementOrCharAt(isolate, object, index); 4879 return GetElementOrCharAt(isolate, object, index);
4890 } else { 4880 } else {
4891 return object->GetProperty(*name); 4881 return object->GetProperty(*name);
4892 } 4882 }
4893 } 4883 }
4894 4884
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
5052 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { 5042 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
5053 HandleScope scope(isolate); 5043 HandleScope scope(isolate);
5054 ASSERT(args.length() == 4); 5044 ASSERT(args.length() == 4);
5055 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); 5045 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5056 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 5046 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5057 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); 5047 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5058 CONVERT_SMI_ARG_CHECKED(unchecked, 3); 5048 CONVERT_SMI_ARG_CHECKED(unchecked, 3);
5059 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 5049 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5060 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 5050 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5061 5051
5062 LookupResult result(isolate); 5052 LookupResult lookup(isolate);
5063 js_object->LocalLookupRealNamedProperty(*name, &result); 5053 js_object->LocalLookupRealNamedProperty(*name, &lookup);
5064 5054
5065 // Special case for callback properties. 5055 // Special case for callback properties.
5066 if (result.IsPropertyCallbacks()) { 5056 if (lookup.IsPropertyCallbacks()) {
5067 Object* callback = result.GetCallbackObject(); 5057 Handle<Object> callback(lookup.GetCallbackObject(), isolate);
5068 // To be compatible with Safari we do not change the value on API objects 5058 // To be compatible with Safari we do not change the value on API objects
5069 // in Object.defineProperty(). Firefox disagrees here, and actually changes 5059 // in Object.defineProperty(). Firefox disagrees here, and actually changes
5070 // the value. 5060 // the value.
5071 if (callback->IsAccessorInfo()) { 5061 if (callback->IsAccessorInfo()) {
5072 return isolate->heap()->undefined_value(); 5062 return isolate->heap()->undefined_value();
5073 } 5063 }
5074 // Avoid redefining foreign callback as data property, just use the stored 5064 // Avoid redefining foreign callback as data property, just use the stored
5075 // setter to update the value instead. 5065 // setter to update the value instead.
5076 // TODO(mstarzinger): So far this only works if property attributes don't 5066 // TODO(mstarzinger): So far this only works if property attributes don't
5077 // change, this should be fixed once we cleanup the underlying code. 5067 // change, this should be fixed once we cleanup the underlying code.
5078 if (callback->IsForeign() && result.GetAttributes() == attr) { 5068 if (callback->IsForeign() && lookup.GetAttributes() == attr) {
5079 Handle<Object> result_object = 5069 Handle<Object> result_object =
5080 JSObject::SetPropertyWithCallback(js_object, 5070 JSObject::SetPropertyWithCallback(js_object,
5081 handle(callback, isolate), 5071 callback,
5082 name, 5072 name,
5083 obj_value, 5073 obj_value,
5084 handle(result.holder()), 5074 handle(lookup.holder()),
5085 kStrictMode); 5075 kStrictMode);
5086 RETURN_IF_EMPTY_HANDLE(isolate, result_object); 5076 RETURN_IF_EMPTY_HANDLE(isolate, result_object);
5087 return *result_object; 5077 return *result_object;
5088 } 5078 }
5089 } 5079 }
5090 5080
5091 // Take special care when attributes are different and there is already 5081 // Take special care when attributes are different and there is already
5092 // a property. For simplicity we normalize the property which enables us 5082 // a property. For simplicity we normalize the property which enables us
5093 // to not worry about changing the instance_descriptor and creating a new 5083 // to not worry about changing the instance_descriptor and creating a new
5094 // map. The current version of SetObjectProperty does not handle attributes 5084 // map. The current version of SetObjectProperty does not handle attributes
5095 // correctly in the case where a property is a field and is reset with 5085 // correctly in the case where a property is a field and is reset with
5096 // new attributes. 5086 // new attributes.
5097 if (result.IsFound() && 5087 if (lookup.IsFound() &&
5098 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { 5088 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
5099 // New attributes - normalize to avoid writing to instance descriptor 5089 // New attributes - normalize to avoid writing to instance descriptor
5100 if (js_object->IsJSGlobalProxy()) { 5090 if (js_object->IsJSGlobalProxy()) {
5101 // Since the result is a property, the prototype will exist so 5091 // Since the result is a property, the prototype will exist so
5102 // we don't have to check for null. 5092 // we don't have to check for null.
5103 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); 5093 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
5104 } 5094 }
5105 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 5095 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5106 // Use IgnoreAttributes version since a readonly property may be 5096 // Use IgnoreAttributes version since a readonly property may be
5107 // overridden and SetProperty does not allow this. 5097 // overridden and SetProperty does not allow this.
5108 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5098 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5109 js_object, name, obj_value, attr); 5099 js_object, name, obj_value, attr);
5110 RETURN_IF_EMPTY_HANDLE(isolate, result); 5100 RETURN_IF_EMPTY_HANDLE(isolate, result);
5111 return *result; 5101 return *result;
5112 } 5102 }
5113 5103
5114 return Runtime::ForceSetObjectProperty(isolate, 5104 Handle<Object> result = Runtime::ForceSetObjectProperty(isolate, js_object,
5115 js_object, 5105 name,
5116 name, 5106 obj_value,
5117 obj_value, 5107 attr);
5118 attr); 5108 RETURN_IF_EMPTY_HANDLE(isolate, result);
5109 return *result;
5119 } 5110 }
5120 5111
5121 5112
5122 // Return property without being observable by accessors or interceptors. 5113 // Return property without being observable by accessors or interceptors.
5123 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { 5114 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
5124 SealHandleScope shs(isolate); 5115 SealHandleScope shs(isolate);
5125 ASSERT(args.length() == 2); 5116 ASSERT(args.length() == 2);
5126 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5117 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5127 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 5118 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5128 LookupResult lookup(isolate); 5119 LookupResult lookup(isolate);
(...skipping 13 matching lines...) Expand all
5142 case INTERCEPTOR: 5133 case INTERCEPTOR:
5143 case TRANSITION: 5134 case TRANSITION:
5144 return isolate->heap()->undefined_value(); 5135 return isolate->heap()->undefined_value();
5145 case NONEXISTENT: 5136 case NONEXISTENT:
5146 UNREACHABLE(); 5137 UNREACHABLE();
5147 } 5138 }
5148 return isolate->heap()->undefined_value(); 5139 return isolate->heap()->undefined_value();
5149 } 5140 }
5150 5141
5151 5142
5152 MaybeObject* Runtime::SetObjectPropertyOrFail( 5143 Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
5153 Isolate* isolate, 5144 Handle<Object> object,
5154 Handle<Object> object, 5145 Handle<Object> key,
5155 Handle<Object> key, 5146 Handle<Object> value,
5156 Handle<Object> value, 5147 PropertyAttributes attr,
5157 PropertyAttributes attr, 5148 StrictModeFlag strict_mode) {
5158 StrictModeFlag strict_mode) {
5159 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
5160 SetObjectProperty(isolate, object, key, value, attr, strict_mode));
5161 }
5162
5163
5164 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
5165 Handle<Object> object,
5166 Handle<Object> key,
5167 Handle<Object> value,
5168 PropertyAttributes attr,
5169 StrictModeFlag strict_mode) {
5170 SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY; 5149 SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
5171 HandleScope scope(isolate);
5172 5150
5173 if (object->IsUndefined() || object->IsNull()) { 5151 if (object->IsUndefined() || object->IsNull()) {
5174 Handle<Object> args[2] = { key, object }; 5152 Handle<Object> args[2] = { key, object };
5175 Handle<Object> error = 5153 Handle<Object> error =
5176 isolate->factory()->NewTypeError("non_object_property_store", 5154 isolate->factory()->NewTypeError("non_object_property_store",
5177 HandleVector(args, 2)); 5155 HandleVector(args, 2));
5178 return isolate->Throw(*error); 5156 isolate->Throw(*error);
5157 return Handle<Object>();
5179 } 5158 }
5180 5159
5181 if (object->IsJSProxy()) { 5160 if (object->IsJSProxy()) {
5182 bool has_pending_exception = false; 5161 bool has_pending_exception = false;
5183 Handle<Object> name_object = key->IsSymbol() 5162 Handle<Object> name_object = key->IsSymbol()
5184 ? key : Execution::ToString(isolate, key, &has_pending_exception); 5163 ? key : Execution::ToString(isolate, key, &has_pending_exception);
5185 if (has_pending_exception) return Failure::Exception(); 5164 if (has_pending_exception) return Handle<Object>(); // exception
5186 Handle<Name> name = Handle<Name>::cast(name_object); 5165 Handle<Name> name = Handle<Name>::cast(name_object);
5187 Handle<Object> result = JSReceiver::SetProperty( 5166 return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
5188 Handle<JSProxy>::cast(object), name, value, attr, strict_mode); 5167 attr,
5189 RETURN_IF_EMPTY_HANDLE(isolate, result); 5168 strict_mode);
5190 return *result;
5191 } 5169 }
5192 5170
5193 // If the object isn't a JavaScript object, we ignore the store. 5171 // If the object isn't a JavaScript object, we ignore the store.
5194 if (!object->IsJSObject()) return *value; 5172 if (!object->IsJSObject()) return value;
5195 5173
5196 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 5174 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5197 5175
5198 // Check if the given key is an array index. 5176 // Check if the given key is an array index.
5199 uint32_t index; 5177 uint32_t index;
5200 if (key->ToArrayIndex(&index)) { 5178 if (key->ToArrayIndex(&index)) {
5201 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 5179 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5202 // of a string using [] notation. We need to support this too in 5180 // of a string using [] notation. We need to support this too in
5203 // JavaScript. 5181 // JavaScript.
5204 // In the case of a String object we just need to redirect the assignment to 5182 // In the case of a String object we just need to redirect the assignment to
5205 // the underlying string if the index is in range. Since the underlying 5183 // the underlying string if the index is in range. Since the underlying
5206 // string does nothing with the assignment then we can ignore such 5184 // string does nothing with the assignment then we can ignore such
5207 // assignments. 5185 // assignments.
5208 if (js_object->IsStringObjectWithCharacterAt(index)) { 5186 if (js_object->IsStringObjectWithCharacterAt(index)) {
5209 return *value; 5187 return value;
5210 } 5188 }
5211 5189
5212 js_object->ValidateElements(); 5190 js_object->ValidateElements();
5213 if (js_object->HasExternalArrayElements()) { 5191 if (js_object->HasExternalArrayElements()) {
5214 if (!value->IsNumber() && !value->IsUndefined()) { 5192 if (!value->IsNumber() && !value->IsUndefined()) {
5215 bool has_exception; 5193 bool has_exception;
5216 Handle<Object> number = 5194 Handle<Object> number =
5217 Execution::ToNumber(isolate, value, &has_exception); 5195 Execution::ToNumber(isolate, value, &has_exception);
5218 if (has_exception) return Failure::Exception(); 5196 if (has_exception) return Handle<Object>(); // exception
5219 value = number; 5197 value = number;
5220 } 5198 }
5221 } 5199 }
5222 MaybeObject* result = js_object->SetElement( 5200 Handle<Object> result = JSObject::SetElement(js_object, index, value, attr,
5223 index, *value, attr, strict_mode, true, set_mode); 5201 strict_mode,
5202 true,
5203 set_mode);
5224 js_object->ValidateElements(); 5204 js_object->ValidateElements();
5225 if (result->IsFailure()) return result; 5205 return result.is_null() ? result : value;
5226 return *value;
5227 } 5206 }
5228 5207
5229 if (key->IsName()) { 5208 if (key->IsName()) {
5230 Handle<Name> name = Handle<Name>::cast(key); 5209 Handle<Name> name = Handle<Name>::cast(key);
5231 if (name->AsArrayIndex(&index)) { 5210 if (name->AsArrayIndex(&index)) {
5232 if (js_object->HasExternalArrayElements()) { 5211 if (js_object->HasExternalArrayElements()) {
5233 if (!value->IsNumber() && !value->IsUndefined()) { 5212 if (!value->IsNumber() && !value->IsUndefined()) {
5234 bool has_exception; 5213 bool has_exception;
5235 Handle<Object> number = 5214 Handle<Object> number =
5236 Execution::ToNumber(isolate, value, &has_exception); 5215 Execution::ToNumber(isolate, value, &has_exception);
5237 if (has_exception) return Failure::Exception(); 5216 if (has_exception) return Handle<Object>(); // exception
5238 value = number; 5217 value = number;
5239 } 5218 }
5240 } 5219 }
5241 MaybeObject* result = js_object->SetElement( 5220 return JSObject::SetElement(js_object, index, value, attr, strict_mode,
5242 index, *value, attr, strict_mode, true, set_mode); 5221 true,
5243 if (result->IsFailure()) return result; 5222 set_mode);
5244 } else { 5223 } else {
5245 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5224 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5246 Handle<Object> result = 5225 return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5247 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5248 RETURN_IF_EMPTY_HANDLE(isolate, result);
5249 } 5226 }
5250 return *value;
5251 } 5227 }
5252 5228
5253 // Call-back into JavaScript to convert the key to a string. 5229 // Call-back into JavaScript to convert the key to a string.
5254 bool has_pending_exception = false; 5230 bool has_pending_exception = false;
5255 Handle<Object> converted = 5231 Handle<Object> converted =
5256 Execution::ToString(isolate, key, &has_pending_exception); 5232 Execution::ToString(isolate, key, &has_pending_exception);
5257 if (has_pending_exception) return Failure::Exception(); 5233 if (has_pending_exception) return Handle<Object>(); // exception
5258 Handle<String> name = Handle<String>::cast(converted); 5234 Handle<String> name = Handle<String>::cast(converted);
5259 5235
5260 if (name->AsArrayIndex(&index)) { 5236 if (name->AsArrayIndex(&index)) {
5261 return js_object->SetElement( 5237 return JSObject::SetElement(js_object, index, value, attr, strict_mode,
5262 index, *value, attr, strict_mode, true, set_mode); 5238 true,
5239 set_mode);
5263 } else { 5240 } else {
5264 Handle<Object> result = 5241 return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5265 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5266 RETURN_IF_EMPTY_HANDLE(isolate, result);
5267 return *result;
5268 } 5242 }
5269 } 5243 }
5270 5244
5271 5245
5272 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 5246 Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate,
5273 Handle<JSObject> js_object, 5247 Handle<JSObject> js_object,
5274 Handle<Object> key, 5248 Handle<Object> key,
5275 Handle<Object> value, 5249 Handle<Object> value,
5276 PropertyAttributes attr) { 5250 PropertyAttributes attr) {
5277 HandleScope scope(isolate);
5278
5279 // Check if the given key is an array index. 5251 // Check if the given key is an array index.
5280 uint32_t index; 5252 uint32_t index;
5281 if (key->ToArrayIndex(&index)) { 5253 if (key->ToArrayIndex(&index)) {
5282 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 5254 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5283 // of a string using [] notation. We need to support this too in 5255 // of a string using [] notation. We need to support this too in
5284 // JavaScript. 5256 // JavaScript.
5285 // In the case of a String object we just need to redirect the assignment to 5257 // In the case of a String object we just need to redirect the assignment to
5286 // the underlying string if the index is in range. Since the underlying 5258 // the underlying string if the index is in range. Since the underlying
5287 // string does nothing with the assignment then we can ignore such 5259 // string does nothing with the assignment then we can ignore such
5288 // assignments. 5260 // assignments.
5289 if (js_object->IsStringObjectWithCharacterAt(index)) { 5261 if (js_object->IsStringObjectWithCharacterAt(index)) {
5290 return *value; 5262 return value;
5291 } 5263 }
5292 5264
5293 return js_object->SetElement( 5265 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5294 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5266 false,
5267 DEFINE_PROPERTY);
5295 } 5268 }
5296 5269
5297 if (key->IsName()) { 5270 if (key->IsName()) {
5298 Handle<Name> name = Handle<Name>::cast(key); 5271 Handle<Name> name = Handle<Name>::cast(key);
5299 if (name->AsArrayIndex(&index)) { 5272 if (name->AsArrayIndex(&index)) {
5300 return js_object->SetElement( 5273 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5301 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5274 false,
5275 DEFINE_PROPERTY);
5302 } else { 5276 } else {
5303 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5277 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5304 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5278 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name,
5305 js_object, name, value, attr); 5279 value, attr);
5306 RETURN_IF_EMPTY_HANDLE(isolate, result);
5307 return *result;
5308 } 5280 }
5309 } 5281 }
5310 5282
5311 // Call-back into JavaScript to convert the key to a string. 5283 // Call-back into JavaScript to convert the key to a string.
5312 bool has_pending_exception = false; 5284 bool has_pending_exception = false;
5313 Handle<Object> converted = 5285 Handle<Object> converted =
5314 Execution::ToString(isolate, key, &has_pending_exception); 5286 Execution::ToString(isolate, key, &has_pending_exception);
5315 if (has_pending_exception) return Failure::Exception(); 5287 if (has_pending_exception) return Handle<Object>(); // exception
5316 Handle<String> name = Handle<String>::cast(converted); 5288 Handle<String> name = Handle<String>::cast(converted);
5317 5289
5318 if (name->AsArrayIndex(&index)) { 5290 if (name->AsArrayIndex(&index)) {
5319 return js_object->SetElement( 5291 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5320 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5292 false,
5293 DEFINE_PROPERTY);
5321 } else { 5294 } else {
5322 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5295 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, value,
5323 js_object, name, value, attr); 5296 attr);
5324 RETURN_IF_EMPTY_HANDLE(isolate, result);
5325 return *result;
5326 } 5297 }
5327 } 5298 }
5328 5299
5329 5300
5330 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, 5301 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
5331 Handle<JSReceiver> receiver, 5302 Handle<JSReceiver> receiver,
5332 Handle<Object> key, 5303 Handle<Object> key,
5333 JSReceiver::DeleteMode mode) { 5304 JSReceiver::DeleteMode mode) {
5334 HandleScope scope(isolate); 5305 HandleScope scope(isolate);
5335 5306
(...skipping 28 matching lines...) Expand all
5364 } 5335 }
5365 5336
5366 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5337 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5367 Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode); 5338 Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode);
5368 RETURN_IF_EMPTY_HANDLE(isolate, result); 5339 RETURN_IF_EMPTY_HANDLE(isolate, result);
5369 return *result; 5340 return *result;
5370 } 5341 }
5371 5342
5372 5343
5373 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { 5344 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
5374 SealHandleScope shs(isolate); 5345 HandleScope scope(isolate);
5375 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); 5346 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
5376 5347
5377 Handle<Object> object = args.at<Object>(0); 5348 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5378 Handle<Object> key = args.at<Object>(1); 5349 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5379 Handle<Object> value = args.at<Object>(2); 5350 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5380 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); 5351 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
5381 RUNTIME_ASSERT( 5352 RUNTIME_ASSERT(
5382 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 5353 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5383 // Compute attributes. 5354 // Compute attributes.
5384 PropertyAttributes attributes = 5355 PropertyAttributes attributes =
5385 static_cast<PropertyAttributes>(unchecked_attributes); 5356 static_cast<PropertyAttributes>(unchecked_attributes);
5386 5357
5387 StrictModeFlag strict_mode = kNonStrictMode; 5358 StrictModeFlag strict_mode = kNonStrictMode;
5388 if (args.length() == 5) { 5359 if (args.length() == 5) {
5389 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4); 5360 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_flag, 4);
5390 strict_mode = strict_mode_flag; 5361 strict_mode = strict_mode_flag;
5391 } 5362 }
5392 5363
5393 return Runtime::SetObjectProperty(isolate, 5364 Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
5394 object, 5365 value,
5395 key, 5366 attributes,
5396 value, 5367 strict_mode);
5397 attributes, 5368 RETURN_IF_EMPTY_HANDLE(isolate, result);
5398 strict_mode); 5369 return *result;
5399 } 5370 }
5400 5371
5401 5372
5402 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) { 5373 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
5403 HandleScope scope(isolate); 5374 HandleScope scope(isolate);
5404 RUNTIME_ASSERT(args.length() == 2); 5375 RUNTIME_ASSERT(args.length() == 2);
5405 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); 5376 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
5406 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); 5377 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
5407 JSObject::TransitionElementsKind(array, map->elements_kind()); 5378 JSObject::TransitionElementsKind(array, map->elements_kind());
5408 return *array; 5379 return *array;
5409 } 5380 }
5410 5381
5411 5382
5412 // Set the native flag on the function. 5383 // Set the native flag on the function.
5413 // This is used to decide if we should transform null and undefined 5384 // This is used to decide if we should transform null and undefined
5414 // into the global object when doing call and apply. 5385 // into the global object when doing call and apply.
5415 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { 5386 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
5416 SealHandleScope shs(isolate); 5387 SealHandleScope shs(isolate);
5417 RUNTIME_ASSERT(args.length() == 1); 5388 RUNTIME_ASSERT(args.length() == 1);
5418 5389
5390 CONVERT_ARG_CHECKED(Object, object, 0);
5391
5392 if (object->IsJSFunction()) {
5393 JSFunction* func = JSFunction::cast(object);
5394 func->shared()->set_native(true);
5395 }
5396 return isolate->heap()->undefined_value();
5397 }
5398
5399
5400 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
5401 SealHandleScope shs(isolate);
5402 RUNTIME_ASSERT(args.length() == 1);
5403
5419 Handle<Object> object = args.at<Object>(0); 5404 Handle<Object> object = args.at<Object>(0);
5420 5405
5421 if (object->IsJSFunction()) { 5406 if (object->IsJSFunction()) {
5422 JSFunction* func = JSFunction::cast(*object); 5407 JSFunction* func = JSFunction::cast(*object);
5423 func->shared()->set_native(true); 5408 func->shared()->set_inline_builtin(true);
5424 } 5409 }
5425 return isolate->heap()->undefined_value(); 5410 return isolate->heap()->undefined_value();
5426 } 5411 }
5427 5412
5428 5413
5429 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { 5414 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
5430 HandleScope scope(isolate); 5415 HandleScope scope(isolate);
5431 RUNTIME_ASSERT(args.length() == 5); 5416 RUNTIME_ASSERT(args.length() == 5);
5432 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5417 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5433 CONVERT_SMI_ARG_CHECKED(store_index, 1); 5418 CONVERT_SMI_ARG_CHECKED(store_index, 1);
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
6215 6200
6216 // Create a number object from the value. 6201 // Create a number object from the value.
6217 return isolate->heap()->NumberFromDouble(value); 6202 return isolate->heap()->NumberFromDouble(value);
6218 } 6203 }
6219 6204
6220 6205
6221 template <class Converter> 6206 template <class Converter>
6222 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( 6207 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
6223 Isolate* isolate, 6208 Isolate* isolate,
6224 String* s, 6209 String* s,
6210 String::Encoding result_encoding,
6225 int length, 6211 int length,
6226 int input_string_length, 6212 int input_string_length,
6227 unibrow::Mapping<Converter, 128>* mapping) { 6213 unibrow::Mapping<Converter, 128>* mapping) {
6228 // We try this twice, once with the assumption that the result is no longer 6214 // We try this twice, once with the assumption that the result is no longer
6229 // than the input and, if that assumption breaks, again with the exact 6215 // than the input and, if that assumption breaks, again with the exact
6230 // length. This may not be pretty, but it is nicer than what was here before 6216 // length. This may not be pretty, but it is nicer than what was here before
6231 // and I hereby claim my vaffel-is. 6217 // and I hereby claim my vaffel-is.
6232 // 6218 //
6233 // Allocate the resulting string. 6219 // Allocate the resulting string.
6234 // 6220 //
6235 // NOTE: This assumes that the upper/lower case of an ASCII 6221 // NOTE: This assumes that the upper/lower case of an ASCII
6236 // character is also ASCII. This is currently the case, but it 6222 // character is also ASCII. This is currently the case, but it
6237 // might break in the future if we implement more context and locale 6223 // might break in the future if we implement more context and locale
6238 // dependent upper/lower conversions. 6224 // dependent upper/lower conversions.
6239 Object* o; 6225 Object* o;
6240 { MaybeObject* maybe_o = s->IsOneByteRepresentation() 6226 { MaybeObject* maybe_o = result_encoding == String::ONE_BYTE_ENCODING
6241 ? isolate->heap()->AllocateRawOneByteString(length) 6227 ? isolate->heap()->AllocateRawOneByteString(length)
6242 : isolate->heap()->AllocateRawTwoByteString(length); 6228 : isolate->heap()->AllocateRawTwoByteString(length);
6243 if (!maybe_o->ToObject(&o)) return maybe_o; 6229 if (!maybe_o->ToObject(&o)) return maybe_o;
6244 } 6230 }
6245 String* result = String::cast(o); 6231 String* result = String::cast(o);
6246 bool has_changed_character = false; 6232 bool has_changed_character = false;
6247 6233
6234 DisallowHeapAllocation no_gc;
6235
6248 // Convert all characters to upper case, assuming that they will fit 6236 // Convert all characters to upper case, assuming that they will fit
6249 // in the buffer 6237 // in the buffer
6250 Access<ConsStringIteratorOp> op( 6238 Access<ConsStringIteratorOp> op(
6251 isolate->runtime_state()->string_iterator()); 6239 isolate->runtime_state()->string_iterator());
6252 StringCharacterStream stream(s, op.value()); 6240 StringCharacterStream stream(s, op.value());
6253 unibrow::uchar chars[Converter::kMaxWidth]; 6241 unibrow::uchar chars[Converter::kMaxWidth];
6254 // We can assume that the string is not empty 6242 // We can assume that the string is not empty
6255 uc32 current = stream.GetNext(); 6243 uc32 current = stream.GetNext();
6244 // y with umlauts is the only character that stops fitting into one-byte
6245 // when converting to uppercase.
6246 static const uc32 yuml_code = 0xff;
6247 bool ignore_yuml = result->IsSeqTwoByteString() || Converter::kIsToLower;
6256 for (int i = 0; i < length;) { 6248 for (int i = 0; i < length;) {
6257 bool has_next = stream.HasMore(); 6249 bool has_next = stream.HasMore();
6258 uc32 next = has_next ? stream.GetNext() : 0; 6250 uc32 next = has_next ? stream.GetNext() : 0;
6259 int char_length = mapping->get(current, next, chars); 6251 int char_length = mapping->get(current, next, chars);
6260 if (char_length == 0) { 6252 if (char_length == 0) {
6261 // The case conversion of this character is the character itself. 6253 // The case conversion of this character is the character itself.
6262 result->Set(i, current); 6254 result->Set(i, current);
6263 i++; 6255 i++;
6264 } else if (char_length == 1) { 6256 } else if (char_length == 1 && (ignore_yuml || current != yuml_code)) {
6265 // Common case: converting the letter resulted in one character. 6257 // Common case: converting the letter resulted in one character.
6266 ASSERT(static_cast<uc32>(chars[0]) != current); 6258 ASSERT(static_cast<uc32>(chars[0]) != current);
6267 result->Set(i, chars[0]); 6259 result->Set(i, chars[0]);
6268 has_changed_character = true; 6260 has_changed_character = true;
6269 i++; 6261 i++;
6270 } else if (length == input_string_length) { 6262 } else if (length == input_string_length) {
6263 bool found_yuml = (current == yuml_code);
6271 // We've assumed that the result would be as long as the 6264 // We've assumed that the result would be as long as the
6272 // input but here is a character that converts to several 6265 // input but here is a character that converts to several
6273 // characters. No matter, we calculate the exact length 6266 // characters. No matter, we calculate the exact length
6274 // of the result and try the whole thing again. 6267 // of the result and try the whole thing again.
6275 // 6268 //
6276 // Note that this leaves room for optimization. We could just 6269 // Note that this leaves room for optimization. We could just
6277 // memcpy what we already have to the result string. Also, 6270 // memcpy what we already have to the result string. Also,
6278 // the result string is the last object allocated we could 6271 // the result string is the last object allocated we could
6279 // "realloc" it and probably, in the vast majority of cases, 6272 // "realloc" it and probably, in the vast majority of cases,
6280 // extend the existing string to be able to hold the full 6273 // extend the existing string to be able to hold the full
6281 // result. 6274 // result.
6282 int next_length = 0; 6275 int next_length = 0;
6283 if (has_next) { 6276 if (has_next) {
6284 next_length = mapping->get(next, 0, chars); 6277 next_length = mapping->get(next, 0, chars);
6285 if (next_length == 0) next_length = 1; 6278 if (next_length == 0) next_length = 1;
6286 } 6279 }
6287 int current_length = i + char_length + next_length; 6280 int current_length = i + char_length + next_length;
6288 while (stream.HasMore()) { 6281 while (stream.HasMore()) {
6289 current = stream.GetNext(); 6282 current = stream.GetNext();
6283 found_yuml |= (current == yuml_code);
6290 // NOTE: we use 0 as the next character here because, while 6284 // NOTE: we use 0 as the next character here because, while
6291 // the next character may affect what a character converts to, 6285 // the next character may affect what a character converts to,
6292 // it does not in any case affect the length of what it convert 6286 // it does not in any case affect the length of what it convert
6293 // to. 6287 // to.
6294 int char_length = mapping->get(current, 0, chars); 6288 int char_length = mapping->get(current, 0, chars);
6295 if (char_length == 0) char_length = 1; 6289 if (char_length == 0) char_length = 1;
6296 current_length += char_length; 6290 current_length += char_length;
6297 if (current_length > Smi::kMaxValue) { 6291 if (current_length > Smi::kMaxValue) {
6298 isolate->context()->mark_out_of_memory(); 6292 isolate->context()->mark_out_of_memory();
6299 return Failure::OutOfMemoryException(0x13); 6293 return Failure::OutOfMemoryException(0x13);
6300 } 6294 }
6301 } 6295 }
6302 // Try again with the real length. 6296 // Try again with the real length. Return signed if we need
6303 return Smi::FromInt(current_length); 6297 // to allocate a two-byte string for y-umlaut to uppercase.
6298 return (found_yuml && !ignore_yuml) ? Smi::FromInt(-current_length)
6299 : Smi::FromInt(current_length);
6304 } else { 6300 } else {
6305 for (int j = 0; j < char_length; j++) { 6301 for (int j = 0; j < char_length; j++) {
6306 result->Set(i, chars[j]); 6302 result->Set(i, chars[j]);
6307 i++; 6303 i++;
6308 } 6304 }
6309 has_changed_character = true; 6305 has_changed_character = true;
6310 } 6306 }
6311 current = next; 6307 current = next;
6312 } 6308 }
6313 if (has_changed_character) { 6309 if (has_changed_character) {
(...skipping 25 matching lines...) Expand all
6339 // further simplified. 6335 // further simplified.
6340 ASSERT(0 < m && m < n); 6336 ASSERT(0 < m && m < n);
6341 // Has high bit set in every w byte less than n. 6337 // Has high bit set in every w byte less than n.
6342 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; 6338 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6343 // Has high bit set in every w byte greater than m. 6339 // Has high bit set in every w byte greater than m.
6344 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); 6340 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6345 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); 6341 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6346 } 6342 }
6347 6343
6348 6344
6349 enum AsciiCaseConversion { 6345 #ifdef DEBUG
6350 ASCII_TO_LOWER, 6346 static bool CheckFastAsciiConvert(char* dst,
6351 ASCII_TO_UPPER 6347 char* src,
6352 }; 6348 int length,
6349 bool changed,
6350 bool is_to_lower) {
6351 bool expected_changed = false;
6352 for (int i = 0; i < length; i++) {
6353 if (dst[i] == src[i]) continue;
6354 expected_changed = true;
6355 if (is_to_lower) {
6356 ASSERT('A' <= src[i] && src[i] <= 'Z');
6357 ASSERT(dst[i] == src[i] + ('a' - 'A'));
6358 } else {
6359 ASSERT('a' <= src[i] && src[i] <= 'z');
6360 ASSERT(dst[i] == src[i] - ('a' - 'A'));
6361 }
6362 }
6363 return (expected_changed == changed);
6364 }
6365 #endif
6353 6366
6354 6367
6355 template <AsciiCaseConversion dir> 6368 template<class Converter>
6356 struct FastAsciiConverter { 6369 static bool FastAsciiConvert(char* dst,
6357 static bool Convert(char* dst, char* src, int length, bool* changed_out) { 6370 char* src,
6371 int length,
6372 bool* changed_out) {
6358 #ifdef DEBUG 6373 #ifdef DEBUG
6359 char* saved_dst = dst; 6374 char* saved_dst = dst;
6360 char* saved_src = src; 6375 char* saved_src = src;
6361 #endif 6376 #endif
6362 // We rely on the distance between upper and lower case letters 6377 DisallowHeapAllocation no_gc;
6363 // being a known power of 2. 6378 // We rely on the distance between upper and lower case letters
6364 ASSERT('a' - 'A' == (1 << 5)); 6379 // being a known power of 2.
6365 // Boundaries for the range of input characters than require conversion. 6380 ASSERT('a' - 'A' == (1 << 5));
6366 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; 6381 // Boundaries for the range of input characters than require conversion.
6367 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; 6382 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6368 bool changed = false; 6383 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6369 uintptr_t or_acc = 0; 6384 bool changed = false;
6370 char* const limit = src + length; 6385 uintptr_t or_acc = 0;
6386 char* const limit = src + length;
6371 #ifdef V8_HOST_CAN_READ_UNALIGNED 6387 #ifdef V8_HOST_CAN_READ_UNALIGNED
6372 // Process the prefix of the input that requires no conversion one 6388 // Process the prefix of the input that requires no conversion one
6373 // (machine) word at a time. 6389 // (machine) word at a time.
6374 while (src <= limit - sizeof(uintptr_t)) { 6390 while (src <= limit - sizeof(uintptr_t)) {
6375 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6391 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6376 or_acc |= w; 6392 or_acc |= w;
6377 if (AsciiRangeMask(w, lo, hi) != 0) { 6393 if (AsciiRangeMask(w, lo, hi) != 0) {
6378 changed = true; 6394 changed = true;
6379 break; 6395 break;
6380 }
6381 *reinterpret_cast<uintptr_t*>(dst) = w;
6382 src += sizeof(uintptr_t);
6383 dst += sizeof(uintptr_t);
6384 } 6396 }
6385 // Process the remainder of the input performing conversion when 6397 *reinterpret_cast<uintptr_t*>(dst) = w;
6386 // required one word at a time. 6398 src += sizeof(uintptr_t);
6387 while (src <= limit - sizeof(uintptr_t)) { 6399 dst += sizeof(uintptr_t);
6388 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); 6400 }
6389 or_acc |= w; 6401 // Process the remainder of the input performing conversion when
6390 uintptr_t m = AsciiRangeMask(w, lo, hi); 6402 // required one word at a time.
6391 // The mask has high (7th) bit set in every byte that needs 6403 while (src <= limit - sizeof(uintptr_t)) {
6392 // conversion and we know that the distance between cases is 6404 uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
6393 // 1 << 5. 6405 or_acc |= w;
6394 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); 6406 uintptr_t m = AsciiRangeMask(w, lo, hi);
6395 src += sizeof(uintptr_t); 6407 // The mask has high (7th) bit set in every byte that needs
6396 dst += sizeof(uintptr_t); 6408 // conversion and we know that the distance between cases is
6409 // 1 << 5.
6410 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6411 src += sizeof(uintptr_t);
6412 dst += sizeof(uintptr_t);
6413 }
6414 #endif
6415 // Process the last few bytes of the input (or the whole input if
6416 // unaligned access is not supported).
6417 while (src < limit) {
6418 char c = *src;
6419 or_acc |= c;
6420 if (lo < c && c < hi) {
6421 c ^= (1 << 5);
6422 changed = true;
6397 } 6423 }
6398 #endif 6424 *dst = c;
6399 // Process the last few bytes of the input (or the whole input if 6425 ++src;
6400 // unaligned access is not supported). 6426 ++dst;
6401 while (src < limit) { 6427 }
6402 char c = *src; 6428 if ((or_acc & kAsciiMask) != 0) {
6403 or_acc |= c; 6429 return false;
6404 if (lo < c && c < hi) {
6405 c ^= (1 << 5);
6406 changed = true;
6407 }
6408 *dst = c;
6409 ++src;
6410 ++dst;
6411 }
6412 if ((or_acc & kAsciiMask) != 0) {
6413 return false;
6414 }
6415 #ifdef DEBUG
6416 CheckConvert(saved_dst, saved_src, length, changed);
6417 #endif
6418 *changed_out = changed;
6419 return true;
6420 } 6430 }
6421 6431
6422 #ifdef DEBUG 6432 ASSERT(CheckFastAsciiConvert(
6423 static void CheckConvert(char* dst, char* src, int length, bool changed) { 6433 saved_dst, saved_src, length, changed, Converter::kIsToLower));
6424 bool expected_changed = false;
6425 for (int i = 0; i < length; i++) {
6426 if (dst[i] == src[i]) continue;
6427 expected_changed = true;
6428 if (dir == ASCII_TO_LOWER) {
6429 ASSERT('A' <= src[i] && src[i] <= 'Z');
6430 ASSERT(dst[i] == src[i] + ('a' - 'A'));
6431 } else {
6432 ASSERT(dir == ASCII_TO_UPPER);
6433 ASSERT('a' <= src[i] && src[i] <= 'z');
6434 ASSERT(dst[i] == src[i] - ('a' - 'A'));
6435 }
6436 }
6437 ASSERT(expected_changed == changed);
6438 }
6439 #endif
6440 };
6441 6434
6442 6435 *changed_out = changed;
6443 struct ToLowerTraits { 6436 return true;
6444 typedef unibrow::ToLowercase UnibrowConverter; 6437 }
6445
6446 typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter;
6447 };
6448
6449
6450 struct ToUpperTraits {
6451 typedef unibrow::ToUppercase UnibrowConverter;
6452
6453 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter;
6454 };
6455 6438
6456 } // namespace 6439 } // namespace
6457 6440
6458 6441
6459 template <typename ConvertTraits> 6442 template <class Converter>
6460 MUST_USE_RESULT static MaybeObject* ConvertCase( 6443 MUST_USE_RESULT static MaybeObject* ConvertCase(
6461 Arguments args, 6444 Arguments args,
6462 Isolate* isolate, 6445 Isolate* isolate,
6463 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { 6446 unibrow::Mapping<Converter, 128>* mapping) {
6464 SealHandleScope shs(isolate); 6447 SealHandleScope shs(isolate);
6465 CONVERT_ARG_CHECKED(String, s, 0); 6448 CONVERT_ARG_CHECKED(String, s, 0);
6466 s = s->TryFlattenGetString(); 6449 s = s->TryFlattenGetString();
6467 6450
6468 const int length = s->length(); 6451 const int length = s->length();
6469 // Assume that the string is not empty; we need this assumption later 6452 // Assume that the string is not empty; we need this assumption later
6470 if (length == 0) return s; 6453 if (length == 0) return s;
6471 6454
6472 // Simpler handling of ASCII strings. 6455 // Simpler handling of ASCII strings.
6473 // 6456 //
6474 // NOTE: This assumes that the upper/lower case of an ASCII 6457 // NOTE: This assumes that the upper/lower case of an ASCII
6475 // character is also ASCII. This is currently the case, but it 6458 // character is also ASCII. This is currently the case, but it
6476 // might break in the future if we implement more context and locale 6459 // might break in the future if we implement more context and locale
6477 // dependent upper/lower conversions. 6460 // dependent upper/lower conversions.
6478 if (s->IsSeqOneByteString()) { 6461 if (s->IsSeqOneByteString()) {
6479 Object* o; 6462 Object* o;
6480 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); 6463 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length);
6481 if (!maybe_o->ToObject(&o)) return maybe_o; 6464 if (!maybe_o->ToObject(&o)) return maybe_o;
6482 } 6465 }
6483 SeqOneByteString* result = SeqOneByteString::cast(o); 6466 SeqOneByteString* result = SeqOneByteString::cast(o);
6484 bool has_changed_character; 6467 bool has_changed_character;
6485 bool is_ascii = ConvertTraits::AsciiConverter::Convert( 6468 bool is_ascii = FastAsciiConvert<Converter>(
6486 reinterpret_cast<char*>(result->GetChars()), 6469 reinterpret_cast<char*>(result->GetChars()),
6487 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), 6470 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
6488 length, 6471 length,
6489 &has_changed_character); 6472 &has_changed_character);
6490 // If not ASCII, we discard the result and take the 2 byte path. 6473 // If not ASCII, we discard the result and take the 2 byte path.
6491 if (is_ascii) { 6474 if (is_ascii) {
6492 return has_changed_character ? result : s; 6475 return has_changed_character ? result : s;
6493 } 6476 }
6494 } 6477 }
6495 6478
6479 String::Encoding result_encoding = s->IsOneByteRepresentation()
6480 ? String::ONE_BYTE_ENCODING : String::TWO_BYTE_ENCODING;
6496 Object* answer; 6481 Object* answer;
6497 { MaybeObject* maybe_answer = 6482 { MaybeObject* maybe_answer = ConvertCaseHelper(
6498 ConvertCaseHelper(isolate, s, length, length, mapping); 6483 isolate, s, result_encoding, length, length, mapping);
6499 if (!maybe_answer->ToObject(&answer)) return maybe_answer; 6484 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6500 } 6485 }
6501 if (answer->IsSmi()) { 6486 if (answer->IsSmi()) {
6502 // Retry with correct length. 6487 int new_length = Smi::cast(answer)->value();
6503 { MaybeObject* maybe_answer = 6488 if (new_length < 0) {
6504 ConvertCaseHelper(isolate, 6489 result_encoding = String::TWO_BYTE_ENCODING;
6505 s, Smi::cast(answer)->value(), length, mapping); 6490 new_length = -new_length;
6506 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6507 } 6491 }
6492 MaybeObject* maybe_answer = ConvertCaseHelper(
6493 isolate, s, result_encoding, new_length, length, mapping);
6494 if (!maybe_answer->ToObject(&answer)) return maybe_answer;
6508 } 6495 }
6509 return answer; 6496 return answer;
6510 } 6497 }
6511 6498
6512 6499
6513 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) { 6500 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
6514 return ConvertCase<ToLowerTraits>( 6501 return ConvertCase(
6515 args, isolate, isolate->runtime_state()->to_lower_mapping()); 6502 args, isolate, isolate->runtime_state()->to_lower_mapping());
6516 } 6503 }
6517 6504
6518 6505
6519 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) { 6506 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
6520 return ConvertCase<ToUpperTraits>( 6507 return ConvertCase(
6521 args, isolate, isolate->runtime_state()->to_upper_mapping()); 6508 args, isolate, isolate->runtime_state()->to_upper_mapping());
6522 } 6509 }
6523 6510
6524 6511
6525 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { 6512 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
6526 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff; 6513 return unibrow::WhiteSpace::Is(c) || c == 0x200b || c == 0xfeff;
6527 } 6514 }
6528 6515
6529 6516
6530 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) { 6517 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
7840 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) { 7827 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
7841 SealHandleScope shs(isolate); 7828 SealHandleScope shs(isolate);
7842 ASSERT(args.length() == 1); 7829 ASSERT(args.length() == 1);
7843 isolate->counters()->math_tan()->Increment(); 7830 isolate->counters()->math_tan()->Increment();
7844 7831
7845 CONVERT_DOUBLE_ARG_CHECKED(x, 0); 7832 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7846 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); 7833 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
7847 } 7834 }
7848 7835
7849 7836
7837 RUNTIME_FUNCTION(MaybeObject*, Runtime_PopulateTrigonometricTable) {
7838 HandleScope scope(isolate);
7839 ASSERT(args.length() == 3);
7840 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sin_table, 0);
7841 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, cos_table, 1);
7842 CONVERT_SMI_ARG_CHECKED(samples, 2);
7843 RUNTIME_ASSERT(sin_table->type() == kExternalDoubleArray);
7844 RUNTIME_ASSERT(cos_table->type() == kExternalDoubleArray);
7845 double* sin_buffer = reinterpret_cast<double*>(
7846 JSArrayBuffer::cast(sin_table->buffer())->backing_store());
7847 double* cos_buffer = reinterpret_cast<double*>(
7848 JSArrayBuffer::cast(cos_table->buffer())->backing_store());
7849
7850 static const double pi_half = 3.1415926535897932 / 2;
7851 double interval = pi_half / samples;
7852 for (int i = 0; i < samples + 1; i++) {
7853 double sample = sin(i * interval);
7854 sin_buffer[i] = sample;
7855 cos_buffer[samples - i] = sample * interval;
7856 }
7857
7858 // Fill this to catch out of bound accesses when calculating Math.sin(pi/2).
7859 sin_buffer[samples + 1] = sin(pi_half + interval);
7860 cos_buffer[samples + 1] = cos(pi_half + interval) * interval;
7861
7862 return isolate->heap()->undefined_value();
7863 }
7864
7865
7850 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) { 7866 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
7851 SealHandleScope shs(isolate); 7867 SealHandleScope shs(isolate);
7852 ASSERT(args.length() == 2); 7868 ASSERT(args.length() == 2);
7853 7869
7854 CONVERT_SMI_ARG_CHECKED(year, 0); 7870 CONVERT_SMI_ARG_CHECKED(year, 0);
7855 CONVERT_SMI_ARG_CHECKED(month, 1); 7871 CONVERT_SMI_ARG_CHECKED(month, 1);
7856 7872
7857 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month)); 7873 return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
7858 } 7874 }
7859 7875
(...skipping 1888 matching lines...) Expand 10 before | Expand all | Expand 10 after
9748 CONVERT_LANGUAGE_MODE_ARG(language_mode, 3); 9764 CONVERT_LANGUAGE_MODE_ARG(language_mode, 3);
9749 ASSERT(args[4]->IsSmi()); 9765 ASSERT(args[4]->IsSmi());
9750 return CompileGlobalEval(isolate, 9766 return CompileGlobalEval(isolate,
9751 args.at<String>(1), 9767 args.at<String>(1),
9752 args.at<Object>(2), 9768 args.at<Object>(2),
9753 language_mode, 9769 language_mode,
9754 args.smi_at(4)); 9770 args.smi_at(4));
9755 } 9771 }
9756 9772
9757 9773
9774 // Allocate a block of memory in the given space (filled with a filler).
9775 // Used as a fall-back for generated code when the space is full.
9758 static MaybeObject* Allocate(Isolate* isolate, 9776 static MaybeObject* Allocate(Isolate* isolate,
9759 int size, 9777 int size,
9760 AllocationSpace space) { 9778 AllocationSpace space) {
9761 // Allocate a block of memory in the given space (filled with a filler). 9779 Heap* heap = isolate->heap();
9762 // Use as fallback for allocation in generated code when the space
9763 // is full.
9764 SealHandleScope shs(isolate);
9765 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); 9780 RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9766 RUNTIME_ASSERT(size > 0); 9781 RUNTIME_ASSERT(size > 0);
9767 Heap* heap = isolate->heap();
9768 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize()); 9782 RUNTIME_ASSERT(size <= heap->MaxRegularSpaceAllocationSize());
9769 Object* allocation; 9783 HeapObject* allocation;
9770 { MaybeObject* maybe_allocation; 9784 { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space);
9771 if (space == NEW_SPACE) { 9785 if (!maybe_allocation->To(&allocation)) return maybe_allocation;
9772 maybe_allocation = heap->new_space()->AllocateRaw(size);
9773 } else {
9774 ASSERT(space == OLD_POINTER_SPACE || space == OLD_DATA_SPACE);
9775 maybe_allocation = heap->paged_space(space)->AllocateRaw(size);
9776 }
9777 if (maybe_allocation->ToObject(&allocation)) {
9778 heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size);
9779 }
9780 return maybe_allocation;
9781 } 9786 }
9787 #ifdef DEBUG
9788 MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
9789 ASSERT(chunk->owner()->identity() == space);
9790 #endif
9791 heap->CreateFillerObjectAt(allocation->address(), size);
9792 return allocation;
9782 } 9793 }
9783 9794
9784 9795
9785 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) { 9796 RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInNewSpace) {
9786 SealHandleScope shs(isolate); 9797 SealHandleScope shs(isolate);
9787 ASSERT(args.length() == 1); 9798 ASSERT(args.length() == 1);
9788 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0); 9799 CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
9789 return Allocate(isolate, size_smi->value(), NEW_SPACE); 9800 return Allocate(isolate, size_smi->value(), NEW_SPACE);
9790 } 9801 }
9791 9802
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
10541 return string; 10552 return string;
10542 } 10553 }
10543 10554
10544 10555
10545 // Moves all own elements of an object, that are below a limit, to positions 10556 // Moves all own elements of an object, that are below a limit, to positions
10546 // starting at zero. All undefined values are placed after non-undefined values, 10557 // starting at zero. All undefined values are placed after non-undefined values,
10547 // and are followed by non-existing element. Does not change the length 10558 // and are followed by non-existing element. Does not change the length
10548 // property. 10559 // property.
10549 // Returns the number of non-undefined elements collected. 10560 // Returns the number of non-undefined elements collected.
10550 RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) { 10561 RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
10551 SealHandleScope shs(isolate); 10562 HandleScope scope(isolate);
10552 ASSERT(args.length() == 2); 10563 ASSERT(args.length() == 2);
10553 CONVERT_ARG_CHECKED(JSObject, object, 0); 10564 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10554 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); 10565 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10555 return object->PrepareElementsForSort(limit); 10566 return *JSObject::PrepareElementsForSort(object, limit);
10556 } 10567 }
10557 10568
10558 10569
10559 // Move contents of argument 0 (an array) to argument 1 (an array) 10570 // Move contents of argument 0 (an array) to argument 1 (an array)
10560 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { 10571 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
10561 SealHandleScope shs(isolate); 10572 SealHandleScope shs(isolate);
10562 ASSERT(args.length() == 2); 10573 ASSERT(args.length() == 2);
10563 CONVERT_ARG_CHECKED(JSArray, from, 0); 10574 CONVERT_ARG_CHECKED(JSArray, from, 0);
10564 CONVERT_ARG_CHECKED(JSArray, to, 1); 10575 CONVERT_ARG_CHECKED(JSArray, to, 1);
10565 from->ValidateElements(); 10576 from->ValidateElements();
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
11370 // First fill all parameters. 11381 // First fill all parameters.
11371 for (int i = 0; i < scope_info->ParameterCount(); ++i) { 11382 for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11372 Handle<Object> value(i < frame_inspector->GetParametersCount() 11383 Handle<Object> value(i < frame_inspector->GetParametersCount()
11373 ? frame_inspector->GetParameter(i) 11384 ? frame_inspector->GetParameter(i)
11374 : isolate->heap()->undefined_value(), 11385 : isolate->heap()->undefined_value(),
11375 isolate); 11386 isolate);
11376 ASSERT(!value->IsTheHole()); 11387 ASSERT(!value->IsTheHole());
11377 11388
11378 RETURN_IF_EMPTY_HANDLE_VALUE( 11389 RETURN_IF_EMPTY_HANDLE_VALUE(
11379 isolate, 11390 isolate,
11380 SetProperty(isolate, 11391 Runtime::SetObjectProperty(isolate,
11381 target, 11392 target,
11382 Handle<String>(scope_info->ParameterName(i)), 11393 Handle<String>(scope_info->ParameterName(i)),
11383 value, 11394 value,
11384 NONE, 11395 NONE,
11385 kNonStrictMode), 11396 kNonStrictMode),
11386 Handle<JSObject>()); 11397 Handle<JSObject>());
11387 } 11398 }
11388 11399
11389 // Second fill all stack locals. 11400 // Second fill all stack locals.
11390 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { 11401 for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11391 Handle<Object> value(frame_inspector->GetExpression(i), isolate); 11402 Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11392 if (value->IsTheHole()) continue; 11403 if (value->IsTheHole()) continue;
11393 11404
11394 RETURN_IF_EMPTY_HANDLE_VALUE( 11405 RETURN_IF_EMPTY_HANDLE_VALUE(
11395 isolate, 11406 isolate,
11396 SetProperty(isolate, 11407 Runtime::SetObjectProperty(
11397 target, 11408 isolate,
11398 Handle<String>(scope_info->StackLocalName(i)), 11409 target,
11399 value, 11410 Handle<String>(scope_info->StackLocalName(i)),
11400 NONE, 11411 value,
11401 kNonStrictMode), 11412 NONE,
11413 kNonStrictMode),
11402 Handle<JSObject>()); 11414 Handle<JSObject>());
11403 } 11415 }
11404 11416
11405 return target; 11417 return target;
11406 } 11418 }
11407 11419
11408 11420
11409 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, 11421 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11410 Handle<JSObject> target, 11422 Handle<JSObject> target,
11411 Handle<JSFunction> function, 11423 Handle<JSFunction> function,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
11469 Handle<FixedArray> keys = 11481 Handle<FixedArray> keys =
11470 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); 11482 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
11471 if (threw) return Handle<JSObject>(); 11483 if (threw) return Handle<JSObject>();
11472 11484
11473 for (int i = 0; i < keys->length(); i++) { 11485 for (int i = 0; i < keys->length(); i++) {
11474 // Names of variables introduced by eval are strings. 11486 // Names of variables introduced by eval are strings.
11475 ASSERT(keys->get(i)->IsString()); 11487 ASSERT(keys->get(i)->IsString());
11476 Handle<String> key(String::cast(keys->get(i))); 11488 Handle<String> key(String::cast(keys->get(i)));
11477 RETURN_IF_EMPTY_HANDLE_VALUE( 11489 RETURN_IF_EMPTY_HANDLE_VALUE(
11478 isolate, 11490 isolate,
11479 SetProperty(isolate, 11491 Runtime::SetObjectProperty(isolate,
11480 target, 11492 target,
11481 key, 11493 key,
11482 GetProperty(isolate, ext, key), 11494 GetProperty(isolate, ext, key),
11483 NONE, 11495 NONE,
11484 kNonStrictMode), 11496 kNonStrictMode),
11485 Handle<JSObject>()); 11497 Handle<JSObject>());
11486 } 11498 }
11487 } 11499 }
11488 } 11500 }
11489 11501
11490 return target; 11502 return target;
11491 } 11503 }
11492 11504
11493 11505
11494 static Handle<JSObject> MaterializeLocalScope( 11506 static Handle<JSObject> MaterializeLocalScope(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
11574 11586
11575 // Function context extension. These are variables introduced by eval. 11587 // Function context extension. These are variables introduced by eval.
11576 if (function_context->closure() == *function) { 11588 if (function_context->closure() == *function) {
11577 if (function_context->has_extension() && 11589 if (function_context->has_extension() &&
11578 !function_context->IsNativeContext()) { 11590 !function_context->IsNativeContext()) {
11579 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 11591 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11580 11592
11581 if (JSReceiver::HasProperty(ext, variable_name)) { 11593 if (JSReceiver::HasProperty(ext, variable_name)) {
11582 // We don't expect this to do anything except replacing 11594 // We don't expect this to do anything except replacing
11583 // property value. 11595 // property value.
11584 SetProperty(isolate, 11596 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11585 ext, 11597 NONE,
11586 variable_name, 11598 kNonStrictMode);
11587 new_value,
11588 NONE,
11589 kNonStrictMode);
11590 return true; 11599 return true;
11591 } 11600 }
11592 } 11601 }
11593 } 11602 }
11594 } 11603 }
11595 11604
11596 return default_result; 11605 return default_result;
11597 } 11606 }
11598 11607
11599 11608
(...skipping 25 matching lines...) Expand all
11625 Handle<FixedArray> keys = 11634 Handle<FixedArray> keys =
11626 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); 11635 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
11627 if (threw) return Handle<JSObject>(); 11636 if (threw) return Handle<JSObject>();
11628 11637
11629 for (int i = 0; i < keys->length(); i++) { 11638 for (int i = 0; i < keys->length(); i++) {
11630 // Names of variables introduced by eval are strings. 11639 // Names of variables introduced by eval are strings.
11631 ASSERT(keys->get(i)->IsString()); 11640 ASSERT(keys->get(i)->IsString());
11632 Handle<String> key(String::cast(keys->get(i))); 11641 Handle<String> key(String::cast(keys->get(i)));
11633 RETURN_IF_EMPTY_HANDLE_VALUE( 11642 RETURN_IF_EMPTY_HANDLE_VALUE(
11634 isolate, 11643 isolate,
11635 SetProperty(isolate, 11644 Runtime::SetObjectProperty(isolate, closure_scope, key,
11636 closure_scope, 11645 GetProperty(isolate, ext, key),
11637 key, 11646 NONE,
11638 GetProperty(isolate, ext, key), 11647 kNonStrictMode),
11639 NONE,
11640 kNonStrictMode),
11641 Handle<JSObject>()); 11648 Handle<JSObject>());
11642 } 11649 }
11643 } 11650 }
11644 11651
11645 return closure_scope; 11652 return closure_scope;
11646 } 11653 }
11647 11654
11648 11655
11649 // This method copies structure of MaterializeClosure method above. 11656 // This method copies structure of MaterializeClosure method above.
11650 static bool SetClosureVariableValue(Isolate* isolate, 11657 static bool SetClosureVariableValue(Isolate* isolate,
(...skipping 10 matching lines...) Expand all
11661 isolate, scope_info, context, variable_name, new_value)) { 11668 isolate, scope_info, context, variable_name, new_value)) {
11662 return true; 11669 return true;
11663 } 11670 }
11664 11671
11665 // Properties from the function context extension. This will 11672 // Properties from the function context extension. This will
11666 // be variables introduced by eval. 11673 // be variables introduced by eval.
11667 if (context->has_extension()) { 11674 if (context->has_extension()) {
11668 Handle<JSObject> ext(JSObject::cast(context->extension())); 11675 Handle<JSObject> ext(JSObject::cast(context->extension()));
11669 if (JSReceiver::HasProperty(ext, variable_name)) { 11676 if (JSReceiver::HasProperty(ext, variable_name)) {
11670 // We don't expect this to do anything except replacing property value. 11677 // We don't expect this to do anything except replacing property value.
11671 SetProperty(isolate, 11678 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11672 ext, 11679 NONE,
11673 variable_name, 11680 kNonStrictMode);
11674 new_value,
11675 NONE,
11676 kNonStrictMode);
11677 return true; 11681 return true;
11678 } 11682 }
11679 } 11683 }
11680 11684
11681 return false; 11685 return false;
11682 } 11686 }
11683 11687
11684 11688
11685 // Create a plain JSObject which materializes the scope for the specified 11689 // Create a plain JSObject which materializes the scope for the specified
11686 // catch context. 11690 // catch context.
11687 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate, 11691 static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
11688 Handle<Context> context) { 11692 Handle<Context> context) {
11689 ASSERT(context->IsCatchContext()); 11693 ASSERT(context->IsCatchContext());
11690 Handle<String> name(String::cast(context->extension())); 11694 Handle<String> name(String::cast(context->extension()));
11691 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), 11695 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
11692 isolate); 11696 isolate);
11693 Handle<JSObject> catch_scope = 11697 Handle<JSObject> catch_scope =
11694 isolate->factory()->NewJSObject(isolate->object_function()); 11698 isolate->factory()->NewJSObject(isolate->object_function());
11695 RETURN_IF_EMPTY_HANDLE_VALUE( 11699 RETURN_IF_EMPTY_HANDLE_VALUE(
11696 isolate, 11700 isolate,
11697 SetProperty(isolate, 11701 Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
11698 catch_scope, 11702 NONE,
11699 name, 11703 kNonStrictMode),
11700 thrown_object,
11701 NONE,
11702 kNonStrictMode),
11703 Handle<JSObject>()); 11704 Handle<JSObject>());
11704 return catch_scope; 11705 return catch_scope;
11705 } 11706 }
11706 11707
11707 11708
11708 static bool SetCatchVariableValue(Isolate* isolate, 11709 static bool SetCatchVariableValue(Isolate* isolate,
11709 Handle<Context> context, 11710 Handle<Context> context,
11710 Handle<String> variable_name, 11711 Handle<String> variable_name,
11711 Handle<Object> new_value) { 11712 Handle<Object> new_value) {
11712 ASSERT(context->IsCatchContext()); 11713 ASSERT(context->IsCatchContext());
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
12710 // Skip if "arguments" is already taken. 12711 // Skip if "arguments" is already taken.
12711 if (!function->shared()->is_function() || 12712 if (!function->shared()->is_function() ||
12712 JSReceiver::HasLocalProperty(target, 12713 JSReceiver::HasLocalProperty(target,
12713 isolate->factory()->arguments_string())) { 12714 isolate->factory()->arguments_string())) {
12714 return target; 12715 return target;
12715 } 12716 }
12716 12717
12717 // FunctionGetArguments can't throw an exception. 12718 // FunctionGetArguments can't throw an exception.
12718 Handle<JSObject> arguments = Handle<JSObject>::cast( 12719 Handle<JSObject> arguments = Handle<JSObject>::cast(
12719 Accessors::FunctionGetArguments(function)); 12720 Accessors::FunctionGetArguments(function));
12720 SetProperty(isolate, 12721 Runtime::SetObjectProperty(isolate, target,
12721 target, 12722 isolate->factory()->arguments_string(),
12722 isolate->factory()->arguments_string(), 12723 arguments,
12723 arguments, 12724 ::NONE,
12724 ::NONE, 12725 kNonStrictMode);
12725 kNonStrictMode);
12726 return target; 12726 return target;
12727 } 12727 }
12728 12728
12729 12729
12730 // Compile and evaluate source for the given context. 12730 // Compile and evaluate source for the given context.
12731 static MaybeObject* DebugEvaluate(Isolate* isolate, 12731 static MaybeObject* DebugEvaluate(Isolate* isolate,
12732 Handle<Context> context, 12732 Handle<Context> context,
12733 Handle<Object> context_extension, 12733 Handle<Object> context_extension,
12734 Handle<Object> receiver, 12734 Handle<Object> receiver,
12735 Handle<String> source) { 12735 Handle<String> source) {
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
14745 if (maybe_array->IsFailure()) return maybe_array; 14745 if (maybe_array->IsFailure()) return maybe_array;
14746 maybe_array = ArrayConstructInitializeElements(array, caller_args); 14746 maybe_array = ArrayConstructInitializeElements(array, caller_args);
14747 if (maybe_array->IsFailure()) return maybe_array; 14747 if (maybe_array->IsFailure()) return maybe_array;
14748 return array; 14748 return array;
14749 } 14749 }
14750 14750
14751 14751
14752 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { 14752 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
14753 HandleScope scope(isolate); 14753 HandleScope scope(isolate);
14754 // If we get 2 arguments then they are the stub parameters (constructor, type 14754 // If we get 2 arguments then they are the stub parameters (constructor, type
14755 // info). If we get 3, then the first one is a pointer to the arguments 14755 // info). If we get 4, then the first one is a pointer to the arguments
14756 // passed by the caller. 14756 // passed by the caller, and the last one is the length of the arguments
14757 // passed to the caller (redundant, but useful to check on the deoptimizer
14758 // with an assert).
14757 Arguments empty_args(0, NULL); 14759 Arguments empty_args(0, NULL);
14758 bool no_caller_args = args.length() == 2; 14760 bool no_caller_args = args.length() == 2;
14759 ASSERT(no_caller_args || args.length() == 3); 14761 ASSERT(no_caller_args || args.length() == 4);
14760 int parameters_start = no_caller_args ? 0 : 1; 14762 int parameters_start = no_caller_args ? 0 : 1;
14761 Arguments* caller_args = no_caller_args 14763 Arguments* caller_args = no_caller_args
14762 ? &empty_args 14764 ? &empty_args
14763 : reinterpret_cast<Arguments*>(args[0]); 14765 : reinterpret_cast<Arguments*>(args[0]);
14764 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); 14766 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14765 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); 14767 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
14766 14768 #ifdef DEBUG
14769 if (!no_caller_args) {
14770 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
14771 ASSERT(arg_count == caller_args->length());
14772 }
14773 #endif
14767 return ArrayConstructorCommon(isolate, 14774 return ArrayConstructorCommon(isolate,
14768 constructor, 14775 constructor,
14769 type_info, 14776 type_info,
14770 caller_args); 14777 caller_args);
14771 } 14778 }
14772 14779
14773 14780
14774 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { 14781 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) {
14775 HandleScope scope(isolate); 14782 HandleScope scope(isolate);
14776 Arguments empty_args(0, NULL); 14783 Arguments empty_args(0, NULL);
14777 bool no_caller_args = args.length() == 1; 14784 bool no_caller_args = args.length() == 1;
14778 ASSERT(no_caller_args || args.length() == 2); 14785 ASSERT(no_caller_args || args.length() == 3);
14779 int parameters_start = no_caller_args ? 0 : 1; 14786 int parameters_start = no_caller_args ? 0 : 1;
14780 Arguments* caller_args = no_caller_args 14787 Arguments* caller_args = no_caller_args
14781 ? &empty_args 14788 ? &empty_args
14782 : reinterpret_cast<Arguments*>(args[0]); 14789 : reinterpret_cast<Arguments*>(args[0]);
14783 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); 14790 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
14784 14791 #ifdef DEBUG
14792 if (!no_caller_args) {
14793 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
14794 ASSERT(arg_count == caller_args->length());
14795 }
14796 #endif
14785 return ArrayConstructorCommon(isolate, 14797 return ArrayConstructorCommon(isolate,
14786 constructor, 14798 constructor,
14787 Handle<Object>::null(), 14799 Handle<Object>::null(),
14788 caller_args); 14800 caller_args);
14789 } 14801 }
14790 14802
14791 14803
14792 // ---------------------------------------------------------------------------- 14804 // ----------------------------------------------------------------------------
14793 // Implementation of Runtime 14805 // Implementation of Runtime
14794 14806
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
14866 // Handle last resort GC and make sure to allow future allocations 14878 // Handle last resort GC and make sure to allow future allocations
14867 // to grow the heap without causing GCs (if possible). 14879 // to grow the heap without causing GCs (if possible).
14868 isolate->counters()->gc_last_resort_from_js()->Increment(); 14880 isolate->counters()->gc_last_resort_from_js()->Increment();
14869 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14881 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14870 "Runtime::PerformGC"); 14882 "Runtime::PerformGC");
14871 } 14883 }
14872 } 14884 }
14873 14885
14874 14886
14875 } } // namespace v8::internal 14887 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698