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

Side by Side Diff: src/runtime.cc

Issue 7865023: Revert "Clean up Context::Lookup and its uses." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 ASSERT(!isolate->has_pending_exception()); 1295 ASSERT(!isolate->has_pending_exception());
1296 return isolate->heap()->undefined_value(); 1296 return isolate->heap()->undefined_value();
1297 } 1297 }
1298 1298
1299 1299
1300 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { 1300 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1301 HandleScope scope(isolate); 1301 HandleScope scope(isolate);
1302 ASSERT(args.length() == 4); 1302 ASSERT(args.length() == 4);
1303 1303
1304 CONVERT_ARG_CHECKED(Context, context, 0); 1304 CONVERT_ARG_CHECKED(Context, context, 0);
1305 // Declarations are always done in a function or global context.
1306 ASSERT(context->IsFunctionContext() || context->IsGlobalContext());
1307
1308 Handle<String> name(String::cast(args[1])); 1305 Handle<String> name(String::cast(args[1]));
1309 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); 1306 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1310 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); 1307 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1311 Handle<Object> initial_value(args[3], isolate); 1308 Handle<Object> initial_value(args[3], isolate);
1312 1309
1310 // Declarations are always done in a function or global context.
1311 context = Handle<Context>(context->declaration_context());
1312
1313 int index; 1313 int index;
1314 PropertyAttributes attributes; 1314 PropertyAttributes attributes;
1315 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; 1315 ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1316 BindingFlags binding_flags; 1316 BindingFlags binding_flags;
1317 Handle<Object> holder = 1317 Handle<Object> holder =
1318 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1318 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1319 1319
1320 if (attributes != ABSENT) { 1320 if (attributes != ABSENT) {
1321 // The name was declared before; check for conflicting re-declarations. 1321 // The name was declared before; check for conflicting
1322 // re-declarations: This is similar to the code in parser.cc in
1323 // the AstBuildingParser::Declare function.
1322 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { 1324 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
1323 // Functions are not read-only. 1325 // Functions are not read-only.
1324 ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); 1326 ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
1325 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var"; 1327 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
1326 return ThrowRedeclarationError(isolate, type, name); 1328 return ThrowRedeclarationError(isolate, type, name);
1327 } 1329 }
1328 1330
1329 // Initialize it if necessary. 1331 // Initialize it if necessary.
1330 if (*initial_value != NULL) { 1332 if (*initial_value != NULL) {
1331 if (index >= 0) { 1333 if (index >= 0) {
1332 ASSERT(holder.is_identical_to(context)); 1334 // The variable or constant context slot should always be in
1333 if (((attributes & READ_ONLY) == 0) || 1335 // the function context or the arguments object.
1334 context->get(index)->IsTheHole()) { 1336 if (holder->IsContext()) {
1335 context->set(index, *initial_value); 1337 ASSERT(holder.is_identical_to(context));
1338 if (((attributes & READ_ONLY) == 0) ||
1339 context->get(index)->IsTheHole()) {
1340 context->set(index, *initial_value);
1341 }
1342 } else {
1343 // The holder is an arguments object.
1344 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1345 Handle<Object> result = SetElement(arguments, index, initial_value,
1346 kNonStrictMode);
1347 if (result.is_null()) return Failure::Exception();
1336 } 1348 }
1337 } else { 1349 } else {
1338 // Slow case: The property is in the context extension object of a 1350 // Slow case: The property is not in the FixedArray part of the context.
1339 // function context or the global object of a global context. 1351 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1340 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1341 RETURN_IF_EMPTY_HANDLE( 1352 RETURN_IF_EMPTY_HANDLE(
1342 isolate, 1353 isolate,
1343 SetProperty(object, name, initial_value, mode, kNonStrictMode)); 1354 SetProperty(context_ext, name, initial_value,
1355 mode, kNonStrictMode));
1344 } 1356 }
1345 } 1357 }
1346 1358
1347 } else { 1359 } else {
1348 // The property is not in the function context. It needs to be 1360 // The property is not in the function context. It needs to be
1349 // "declared" in the function context's extension context or as a 1361 // "declared" in the function context's extension context, or in the
1350 // property of the the global object. 1362 // global context.
1351 Handle<JSObject> object; 1363 Handle<JSObject> context_ext;
1352 if (context->has_extension()) { 1364 if (context->has_extension()) {
1353 object = Handle<JSObject>(JSObject::cast(context->extension())); 1365 // The function context's extension context exists - use it.
1366 context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1354 } else { 1367 } else {
1355 // Context extension objects are allocated lazily. 1368 // The function context's extension context does not exists - allocate
1356 ASSERT(context->IsFunctionContext()); 1369 // it.
1357 object = isolate->factory()->NewJSObject( 1370 context_ext = isolate->factory()->NewJSObject(
1358 isolate->context_extension_function()); 1371 isolate->context_extension_function());
1359 context->set_extension(*object); 1372 // And store it in the extension slot.
1373 context->set_extension(*context_ext);
1360 } 1374 }
1361 ASSERT(*object != NULL); 1375 ASSERT(*context_ext != NULL);
1362 1376
1363 // Declare the property by setting it to the initial value if provided, 1377 // Declare the property by setting it to the initial value if provided,
1364 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for 1378 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
1365 // constant declarations). 1379 // constant declarations).
1366 ASSERT(!object->HasLocalProperty(*name)); 1380 ASSERT(!context_ext->HasLocalProperty(*name));
1367 Handle<Object> value(isolate->heap()->undefined_value(), isolate); 1381 Handle<Object> value(isolate->heap()->undefined_value(), isolate);
1368 if (*initial_value != NULL) value = initial_value; 1382 if (*initial_value != NULL) value = initial_value;
1369 // Declaring a const context slot is a conflicting declaration if 1383 // Declaring a const context slot is a conflicting declaration if
1370 // there is a callback with that name in a prototype. It is 1384 // there is a callback with that name in a prototype. It is
1371 // allowed to introduce const variables in 1385 // allowed to introduce const variables in
1372 // JSContextExtensionObjects. They are treated specially in 1386 // JSContextExtensionObjects. They are treated specially in
1373 // SetProperty and no setters are invoked for those since they are 1387 // SetProperty and no setters are invoked for those since they are
1374 // not real JSObjects. 1388 // not real JSObjects.
1375 if (initial_value->IsTheHole() && 1389 if (initial_value->IsTheHole() &&
1376 !object->IsJSContextExtensionObject()) { 1390 !context_ext->IsJSContextExtensionObject()) {
1377 LookupResult lookup; 1391 LookupResult lookup;
1378 object->Lookup(*name, &lookup); 1392 context_ext->Lookup(*name, &lookup);
1379 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { 1393 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
1380 return ThrowRedeclarationError(isolate, "const", name); 1394 return ThrowRedeclarationError(isolate, "const", name);
1381 } 1395 }
1382 } 1396 }
1383 RETURN_IF_EMPTY_HANDLE(isolate, 1397 RETURN_IF_EMPTY_HANDLE(isolate,
1384 SetProperty(object, name, value, mode, 1398 SetProperty(context_ext, name, value, mode,
1385 kNonStrictMode)); 1399 kNonStrictMode));
1386 } 1400 }
1387 1401
1388 return isolate->heap()->undefined_value(); 1402 return isolate->heap()->undefined_value();
1389 } 1403 }
1390 1404
1391 1405
1392 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { 1406 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
1393 NoHandleAllocation nha; 1407 NoHandleAllocation nha;
1394 // args[0] == name 1408 // args[0] == name
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 return *value; 1586 return *value;
1573 } 1587 }
1574 1588
1575 1589
1576 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { 1590 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1577 HandleScope scope(isolate); 1591 HandleScope scope(isolate);
1578 ASSERT(args.length() == 3); 1592 ASSERT(args.length() == 3);
1579 1593
1580 Handle<Object> value(args[0], isolate); 1594 Handle<Object> value(args[0], isolate);
1581 ASSERT(!value->IsTheHole()); 1595 ASSERT(!value->IsTheHole());
1596 CONVERT_ARG_CHECKED(Context, context, 1);
1597 Handle<String> name(String::cast(args[2]));
1582 1598
1583 // Initializations are always done in a function or global context. 1599 // Initializations are always done in a function or global context.
1584 RUNTIME_ASSERT(args[1]->IsContext()); 1600 context = Handle<Context>(context->declaration_context());
1585 Handle<Context> context(Context::cast(args[1])->declaration_context());
1586
1587 Handle<String> name(String::cast(args[2]));
1588 1601
1589 int index; 1602 int index;
1590 PropertyAttributes attributes; 1603 PropertyAttributes attributes;
1591 ContextLookupFlags flags = FOLLOW_CHAINS; 1604 ContextLookupFlags flags = FOLLOW_CHAINS;
1592 BindingFlags binding_flags; 1605 BindingFlags binding_flags;
1593 Handle<Object> holder = 1606 Handle<Object> holder =
1594 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1607 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1595 1608
1609 // In most situations, the property introduced by the const
1610 // declaration should be present in the context extension object.
1611 // However, because declaration and initialization are separate, the
1612 // property might have been deleted (if it was introduced by eval)
1613 // before we reach the initialization point.
1614 //
1615 // Example:
1616 //
1617 // function f() { eval("delete x; const x;"); }
1618 //
1619 // In that case, the initialization behaves like a normal assignment
1620 // to property 'x'.
1596 if (index >= 0) { 1621 if (index >= 0) {
1597 ASSERT(holder->IsContext()); 1622 if (holder->IsContext()) {
1598 // Property was found in a context. Perform the assignment if we 1623 // Property was found in a context. Perform the assignment if we
1599 // found some non-constant or an uninitialized constant. 1624 // found some non-constant or an uninitialized constant.
1600 Handle<Context> context = Handle<Context>::cast(holder); 1625 Handle<Context> context = Handle<Context>::cast(holder);
1601 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) { 1626 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1602 context->set(index, *value); 1627 context->set(index, *value);
1628 }
1629 } else {
1630 // The holder is an arguments object.
1631 ASSERT((attributes & READ_ONLY) == 0);
1632 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1633 RETURN_IF_EMPTY_HANDLE(
1634 isolate,
1635 SetElement(arguments, index, value, kNonStrictMode));
1603 } 1636 }
1604 return *value; 1637 return *value;
1605 } 1638 }
1606 1639
1607 // The property could not be found, we introduce it as a property of the 1640 // The property could not be found, we introduce it in the global
1608 // global object. 1641 // context.
1609 if (attributes == ABSENT) { 1642 if (attributes == ABSENT) {
1610 Handle<JSObject> global = Handle<JSObject>( 1643 Handle<JSObject> global = Handle<JSObject>(
1611 isolate->context()->global()); 1644 isolate->context()->global());
1612 // Strict mode not needed (const disallowed in strict mode). 1645 // Strict mode not needed (const disallowed in strict mode).
1613 RETURN_IF_EMPTY_HANDLE( 1646 RETURN_IF_EMPTY_HANDLE(
1614 isolate, 1647 isolate,
1615 SetProperty(global, name, value, NONE, kNonStrictMode)); 1648 SetProperty(global, name, value, NONE, kNonStrictMode));
1616 return *value; 1649 return *value;
1617 } 1650 }
1618 1651
1619 // The property was present in some function's context extension object, 1652 // The property was present in a context extension object.
1620 // as a property on the subject of a with, or as a property of the global 1653 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1621 // object.
1622 //
1623 // In most situations, eval-introduced consts should still be present in
1624 // the context extension object. However, because declaration and
1625 // initialization are separate, the property might have been deleted
1626 // before we reach the initialization point.
1627 //
1628 // Example:
1629 //
1630 // function f() { eval("delete x; const x;"); }
1631 //
1632 // In that case, the initialization behaves like a normal assignment.
1633 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1634 1654
1635 if (*object == context->extension()) { 1655 if (*context_ext == context->extension()) {
1636 // This is the property that was introduced by the const declaration. 1656 // This is the property that was introduced by the const
1637 // Set it if it hasn't been set before. NOTE: We cannot use 1657 // declaration. Set it if it hasn't been set before. NOTE: We
1638 // GetProperty() to get the current value as it 'unholes' the value. 1658 // cannot use GetProperty() to get the current value as it
1659 // 'unholes' the value.
1639 LookupResult lookup; 1660 LookupResult lookup;
1640 object->LocalLookupRealNamedProperty(*name, &lookup); 1661 context_ext->LocalLookupRealNamedProperty(*name, &lookup);
1641 ASSERT(lookup.IsProperty()); // the property was declared 1662 ASSERT(lookup.IsProperty()); // the property was declared
1642 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only 1663 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
1643 1664
1644 PropertyType type = lookup.type(); 1665 PropertyType type = lookup.type();
1645 if (type == FIELD) { 1666 if (type == FIELD) {
1646 FixedArray* properties = object->properties(); 1667 FixedArray* properties = context_ext->properties();
1647 int index = lookup.GetFieldIndex(); 1668 int index = lookup.GetFieldIndex();
1648 if (properties->get(index)->IsTheHole()) { 1669 if (properties->get(index)->IsTheHole()) {
1649 properties->set(index, *value); 1670 properties->set(index, *value);
1650 } 1671 }
1651 } else if (type == NORMAL) { 1672 } else if (type == NORMAL) {
1652 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { 1673 if (context_ext->GetNormalizedProperty(&lookup)->IsTheHole()) {
1653 object->SetNormalizedProperty(&lookup, *value); 1674 context_ext->SetNormalizedProperty(&lookup, *value);
1654 } 1675 }
1655 } else { 1676 } else {
1656 // We should not reach here. Any real, named property should be 1677 // We should not reach here. Any real, named property should be
1657 // either a field or a dictionary slot. 1678 // either a field or a dictionary slot.
1658 UNREACHABLE(); 1679 UNREACHABLE();
1659 } 1680 }
1660 } else { 1681 } else {
1661 // The property was found on some other object. Set it if it is not a 1682 // The property was found in a different context extension object.
1662 // read-only property. 1683 // Set it if it is not a read-only property.
1663 if ((attributes & READ_ONLY) == 0) { 1684 if ((attributes & READ_ONLY) == 0) {
1664 // Strict mode not needed (const disallowed in strict mode). 1685 // Strict mode not needed (const disallowed in strict mode).
1665 RETURN_IF_EMPTY_HANDLE( 1686 RETURN_IF_EMPTY_HANDLE(
1666 isolate, 1687 isolate,
1667 SetProperty(object, name, value, attributes, kNonStrictMode)); 1688 SetProperty(context_ext, name, value, attributes, kNonStrictMode));
1668 } 1689 }
1669 } 1690 }
1670 1691
1671 return *value; 1692 return *value;
1672 } 1693 }
1673 1694
1674 1695
1675 RUNTIME_FUNCTION(MaybeObject*, 1696 RUNTIME_FUNCTION(MaybeObject*,
1676 Runtime_OptimizeObjectForAddingMultipleProperties) { 1697 Runtime_OptimizeObjectForAddingMultipleProperties) {
1677 HandleScope scope(isolate); 1698 HandleScope scope(isolate);
(...skipping 6857 matching lines...) Expand 10 before | Expand all | Expand 10 after
8535 if (holder.is_null()) { 8556 if (holder.is_null()) {
8536 return isolate->heap()->true_value(); 8557 return isolate->heap()->true_value();
8537 } 8558 }
8538 8559
8539 // If the slot was found in a context, it should be DONT_DELETE. 8560 // If the slot was found in a context, it should be DONT_DELETE.
8540 if (holder->IsContext()) { 8561 if (holder->IsContext()) {
8541 return isolate->heap()->false_value(); 8562 return isolate->heap()->false_value();
8542 } 8563 }
8543 8564
8544 // The slot was found in a JSObject, either a context extension object, 8565 // The slot was found in a JSObject, either a context extension object,
8545 // the global object, or the subject of a with. Try to delete it 8566 // the global object, or an arguments object. Try to delete it
8546 // (respecting DONT_DELETE). 8567 // (respecting DONT_DELETE). For consistency with V8's usual behavior,
8568 // which allows deleting all parameters in functions that mention
8569 // 'arguments', we do this even for the case of slots found on an
8570 // arguments object. The slot was found on an arguments object if the
8571 // index is non-negative.
8547 Handle<JSObject> object = Handle<JSObject>::cast(holder); 8572 Handle<JSObject> object = Handle<JSObject>::cast(holder);
8548 return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION); 8573 if (index >= 0) {
8574 return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
8575 } else {
8576 return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
8577 }
8549 } 8578 }
8550 8579
8551 8580
8552 // A mechanism to return a pair of Object pointers in registers (if possible). 8581 // A mechanism to return a pair of Object pointers in registers (if possible).
8553 // How this is achieved is calling convention-dependent. 8582 // How this is achieved is calling convention-dependent.
8554 // All currently supported x86 compiles uses calling conventions that are cdecl 8583 // All currently supported x86 compiles uses calling conventions that are cdecl
8555 // variants where a 64-bit value is returned in two 32-bit registers 8584 // variants where a 64-bit value is returned in two 32-bit registers
8556 // (edx:eax on ia32, r1:r0 on ARM). 8585 // (edx:eax on ia32, r1:r0 on ARM).
8557 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. 8586 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
8558 // In Win64 calling convention, a struct of two pointers is returned in memory, 8587 // In Win64 calling convention, a struct of two pointers is returned in memory,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
8623 int index; 8652 int index;
8624 PropertyAttributes attributes; 8653 PropertyAttributes attributes;
8625 ContextLookupFlags flags = FOLLOW_CHAINS; 8654 ContextLookupFlags flags = FOLLOW_CHAINS;
8626 BindingFlags binding_flags; 8655 BindingFlags binding_flags;
8627 Handle<Object> holder = context->Lookup(name, 8656 Handle<Object> holder = context->Lookup(name,
8628 flags, 8657 flags,
8629 &index, 8658 &index,
8630 &attributes, 8659 &attributes,
8631 &binding_flags); 8660 &binding_flags);
8632 8661
8633 // If the index is non-negative, the slot has been found in a context. 8662 // If the index is non-negative, the slot has been found in a local
8663 // variable or a parameter. Read it from the context object or the
8664 // arguments object.
8634 if (index >= 0) { 8665 if (index >= 0) {
8635 ASSERT(holder->IsContext()); 8666 // If the "property" we were looking for is a local variable or an
8636 // If the "property" we were looking for is a local variable, the 8667 // argument in a context, the receiver is the global object; see
8637 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. 8668 // ECMA-262, 3rd., 10.1.6 and 10.2.3.
8638 // 8669 //
8639 // Use the hole as the receiver to signal that the receiver is implicit 8670 // Use the hole as the receiver to signal that the receiver is
8640 // and that the global receiver should be used (as distinguished from an 8671 // implicit and that the global receiver should be used.
8641 // explicit receiver that happens to be a global object).
8642 Handle<Object> receiver = isolate->factory()->the_hole_value(); 8672 Handle<Object> receiver = isolate->factory()->the_hole_value();
8643 Object* value = Context::cast(*holder)->get(index); 8673 MaybeObject* value = (holder->IsContext())
8674 ? Context::cast(*holder)->get(index)
8675 : JSObject::cast(*holder)->GetElement(index);
8644 // Check for uninitialized bindings. 8676 // Check for uninitialized bindings.
8645 if (binding_flags == MUTABLE_CHECK_INITIALIZED && value->IsTheHole()) { 8677 if (holder->IsContext() &&
8678 binding_flags == MUTABLE_CHECK_INITIALIZED &&
8679 value->IsTheHole()) {
8646 Handle<Object> reference_error = 8680 Handle<Object> reference_error =
8647 isolate->factory()->NewReferenceError("not_defined", 8681 isolate->factory()->NewReferenceError("not_defined",
8648 HandleVector(&name, 1)); 8682 HandleVector(&name, 1));
8649 return MakePair(isolate->Throw(*reference_error), NULL); 8683 return MakePair(isolate->Throw(*reference_error), NULL);
8650 } else { 8684 } else {
8651 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); 8685 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8652 } 8686 }
8653 } 8687 }
8654 8688
8655 // Otherwise, if the slot was found the holder is a context extension 8689 // If the holder is found, we read the property from it.
8656 // object, subject of a with, or a global object. We read the named 8690 if (!holder.is_null() && holder->IsJSObject()) {
8657 // property from it. 8691 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
8658 if (!holder.is_null()) {
8659 JSObject* object = JSObject::cast(*holder); 8692 JSObject* object = JSObject::cast(*holder);
8660 ASSERT(object->HasProperty(*name)); 8693 Object* receiver;
8694 if (object->IsGlobalObject()) {
8695 receiver = GlobalObject::cast(object)->global_receiver();
8696 } else if (context->is_exception_holder(*holder)) {
8697 // Use the hole as the receiver to signal that the receiver is
8698 // implicit and that the global receiver should be used.
8699 receiver = isolate->heap()->the_hole_value();
8700 } else {
8701 receiver = ComputeReceiverForNonGlobal(isolate, object);
8702 }
8703
8661 // GetProperty below can cause GC. 8704 // GetProperty below can cause GC.
8662 Handle<Object> receiver_handle(object->IsGlobalObject() 8705 Handle<Object> receiver_handle(receiver);
8663 ? GlobalObject::cast(object)->global_receiver()
8664 : ComputeReceiverForNonGlobal(isolate, object));
8665 8706
8666 // No need to unhole the value here. This is taken care of by the 8707 // No need to unhole the value here. This is taken care of by the
8667 // GetProperty function. 8708 // GetProperty function.
8668 MaybeObject* value = object->GetProperty(*name); 8709 MaybeObject* value = object->GetProperty(*name);
8669 return MakePair(value, *receiver_handle); 8710 return MakePair(value, *receiver_handle);
8670 } 8711 }
8671 8712
8672 if (throw_error) { 8713 if (throw_error) {
8673 // The property doesn't exist - throw exception. 8714 // The property doesn't exist - throw exception.
8674 Handle<Object> reference_error = 8715 Handle<Object> reference_error =
8675 isolate->factory()->NewReferenceError("not_defined", 8716 isolate->factory()->NewReferenceError("not_defined",
8676 HandleVector(&name, 1)); 8717 HandleVector(&name, 1));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8709 PropertyAttributes attributes; 8750 PropertyAttributes attributes;
8710 ContextLookupFlags flags = FOLLOW_CHAINS; 8751 ContextLookupFlags flags = FOLLOW_CHAINS;
8711 BindingFlags binding_flags; 8752 BindingFlags binding_flags;
8712 Handle<Object> holder = context->Lookup(name, 8753 Handle<Object> holder = context->Lookup(name,
8713 flags, 8754 flags,
8714 &index, 8755 &index,
8715 &attributes, 8756 &attributes,
8716 &binding_flags); 8757 &binding_flags);
8717 8758
8718 if (index >= 0) { 8759 if (index >= 0) {
8719 // The property was found in a context slot. 8760 if (holder->IsContext()) {
8720 Handle<Context> context = Handle<Context>::cast(holder); 8761 Handle<Context> context = Handle<Context>::cast(holder);
8721 if (binding_flags == MUTABLE_CHECK_INITIALIZED && 8762 if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
8722 context->get(index)->IsTheHole()) { 8763 context->get(index)->IsTheHole()) {
8723 Handle<Object> error = 8764 Handle<Object> error =
8724 isolate->factory()->NewReferenceError("not_defined", 8765 isolate->factory()->NewReferenceError("not_defined",
8725 HandleVector(&name, 1)); 8766 HandleVector(&name, 1));
8726 return isolate->Throw(*error); 8767 return isolate->Throw(*error);
8727 } 8768 }
8728 // Ignore if read_only variable. 8769 // Ignore if read_only variable.
8729 if ((attributes & READ_ONLY) == 0) { 8770 if ((attributes & READ_ONLY) == 0) {
8730 // Context is a fixed array and set cannot fail. 8771 // Context is a fixed array and set cannot fail.
8731 context->set(index, *value); 8772 context->set(index, *value);
8732 } else if (strict_mode == kStrictMode) { 8773 } else if (strict_mode == kStrictMode) {
8733 // Setting read only property in strict mode. 8774 // Setting read only property in strict mode.
8734 Handle<Object> error = 8775 Handle<Object> error =
8735 isolate->factory()->NewTypeError("strict_cannot_assign", 8776 isolate->factory()->NewTypeError("strict_cannot_assign",
8736 HandleVector(&name, 1)); 8777 HandleVector(&name, 1));
8737 return isolate->Throw(*error); 8778 return isolate->Throw(*error);
8779 }
8780 } else {
8781 ASSERT((attributes & READ_ONLY) == 0);
8782 Handle<Object> result =
8783 SetElement(Handle<JSObject>::cast(holder), index, value, strict_mode);
8784 if (result.is_null()) {
8785 ASSERT(isolate->has_pending_exception());
8786 return Failure::Exception();
8787 }
8738 } 8788 }
8739 return *value; 8789 return *value;
8740 } 8790 }
8741 8791
8742 // Slow case: The property is not in a context slot. It is either in a 8792 // Slow case: The property is not in a FixedArray context.
8743 // context extension object, a property of the subject of a with, or a 8793 // It is either in an JSObject extension context or it was not found.
8744 // property of the global object. 8794 Handle<JSObject> context_ext;
8745 Handle<JSObject> object;
8746 8795
8747 if (!holder.is_null()) { 8796 if (!holder.is_null()) {
8748 // The property exists on the holder. 8797 // The property exists in the extension context.
8749 object = Handle<JSObject>::cast(holder); 8798 context_ext = Handle<JSObject>::cast(holder);
8750 } else { 8799 } else {
8751 // The property was not found. 8800 // The property was not found.
8752 ASSERT(attributes == ABSENT); 8801 ASSERT(attributes == ABSENT);
8753 8802
8754 if (strict_mode == kStrictMode) { 8803 if (strict_mode == kStrictMode) {
8755 // Throw in strict mode (assignment to undefined variable). 8804 // Throw in strict mode (assignment to undefined variable).
8756 Handle<Object> error = 8805 Handle<Object> error =
8757 isolate->factory()->NewReferenceError( 8806 isolate->factory()->NewReferenceError(
8758 "not_defined", HandleVector(&name, 1)); 8807 "not_defined", HandleVector(&name, 1));
8759 return isolate->Throw(*error); 8808 return isolate->Throw(*error);
8760 } 8809 }
8761 // In non-strict mode, the property is added to the global object. 8810 // In non-strict mode, the property is stored in the global context.
8762 attributes = NONE; 8811 attributes = NONE;
8763 object = Handle<JSObject>(isolate->context()->global()); 8812 context_ext = Handle<JSObject>(isolate->context()->global());
8764 } 8813 }
8765 8814
8766 // Set the property if it's not read only or doesn't yet exist. 8815 // Set the property, but ignore if read_only variable on the context
8816 // extension object itself.
8767 if ((attributes & READ_ONLY) == 0 || 8817 if ((attributes & READ_ONLY) == 0 ||
8768 (object->GetLocalPropertyAttribute(*name) == ABSENT)) { 8818 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
8769 RETURN_IF_EMPTY_HANDLE( 8819 RETURN_IF_EMPTY_HANDLE(
8770 isolate, 8820 isolate,
8771 SetProperty(object, name, value, NONE, strict_mode)); 8821 SetProperty(context_ext, name, value, NONE, strict_mode));
8772 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { 8822 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
8773 // Setting read only property in strict mode. 8823 // Setting read only property in strict mode.
8774 Handle<Object> error = 8824 Handle<Object> error =
8775 isolate->factory()->NewTypeError( 8825 isolate->factory()->NewTypeError(
8776 "strict_cannot_assign", HandleVector(&name, 1)); 8826 "strict_cannot_assign", HandleVector(&name, 1));
8777 return isolate->Throw(*error); 8827 return isolate->Throw(*error);
8778 } 8828 }
8779 return *value; 8829 return *value;
8780 } 8830 }
8781 8831
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
9166 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 9216 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
9167 ASSERT(Context::cast(frame->context()) == *context); 9217 ASSERT(Context::cast(frame->context()) == *context);
9168 #endif 9218 #endif
9169 9219
9170 // Find where the 'eval' symbol is bound. It is unaliased only if 9220 // Find where the 'eval' symbol is bound. It is unaliased only if
9171 // it is bound in the global context. 9221 // it is bound in the global context.
9172 int index = -1; 9222 int index = -1;
9173 PropertyAttributes attributes = ABSENT; 9223 PropertyAttributes attributes = ABSENT;
9174 BindingFlags binding_flags; 9224 BindingFlags binding_flags;
9175 while (true) { 9225 while (true) {
9176 // Don't follow context chains in Context::Lookup and implement the loop
9177 // up the context chain here, so that we can know the context where eval
9178 // was found.
9179 receiver = context->Lookup(isolate->factory()->eval_symbol(), 9226 receiver = context->Lookup(isolate->factory()->eval_symbol(),
9180 FOLLOW_PROTOTYPE_CHAIN, 9227 FOLLOW_PROTOTYPE_CHAIN,
9181 &index, 9228 &index,
9182 &attributes, 9229 &attributes,
9183 &binding_flags); 9230 &binding_flags);
9184 // Stop search when eval is found or when the global context is 9231 // Stop search when eval is found or when the global context is
9185 // reached. 9232 // reached.
9186 if (attributes != ABSENT || context->IsGlobalContext()) break; 9233 if (attributes != ABSENT || context->IsGlobalContext()) break;
9187 context = Handle<Context>(context->previous(), isolate); 9234 context = Handle<Context>(context->previous(), isolate);
9188 } 9235 }
(...skipping 3908 matching lines...) Expand 10 before | Expand all | Expand 10 after
13097 } else { 13144 } else {
13098 // Handle last resort GC and make sure to allow future allocations 13145 // Handle last resort GC and make sure to allow future allocations
13099 // to grow the heap without causing GCs (if possible). 13146 // to grow the heap without causing GCs (if possible).
13100 isolate->counters()->gc_last_resort_from_js()->Increment(); 13147 isolate->counters()->gc_last_resort_from_js()->Increment();
13101 isolate->heap()->CollectAllGarbage(false); 13148 isolate->heap()->CollectAllGarbage(false);
13102 } 13149 }
13103 } 13150 }
13104 13151
13105 13152
13106 } } // namespace v8::internal 13153 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698