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

Side by Side Diff: src/runtime.cc

Issue 7886002: 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 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 1294
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 // Declarations are always made in a function or global context. In the 1304 CONVERT_ARG_CHECKED(Context, context, 0);
1305 // case of eval code, the context passed is the context of the caller,
1306 // which may be some nested context and not the declaration context.
1307 RUNTIME_ASSERT(args[0]->IsContext());
1308 Handle<Context> context(Context::cast(args[0])->declaration_context());
1309
1310 Handle<String> name(String::cast(args[1])); 1305 Handle<String> name(String::cast(args[1]));
1311 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); 1306 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1312 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); 1307 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1313 Handle<Object> initial_value(args[3], isolate); 1308 Handle<Object> initial_value(args[3], isolate);
1314 1309
1310 // Declarations are always done in a function or global context.
1311 context = Handle<Context>(context->declaration_context());
1312
1315 int index; 1313 int index;
1316 PropertyAttributes attributes; 1314 PropertyAttributes attributes;
1317 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; 1315 ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1318 BindingFlags binding_flags; 1316 BindingFlags binding_flags;
1319 Handle<Object> holder = 1317 Handle<Object> holder =
1320 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1318 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1321 1319
1322 if (attributes != ABSENT) { 1320 if (attributes != ABSENT) {
1323 // 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.
1324 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { 1324 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
1325 // Functions are not read-only. 1325 // Functions are not read-only.
1326 ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); 1326 ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
1327 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var"; 1327 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
1328 return ThrowRedeclarationError(isolate, type, name); 1328 return ThrowRedeclarationError(isolate, type, name);
1329 } 1329 }
1330 1330
1331 // Initialize it if necessary. 1331 // Initialize it if necessary.
1332 if (*initial_value != NULL) { 1332 if (*initial_value != NULL) {
1333 if (index >= 0) { 1333 if (index >= 0) {
1334 ASSERT(holder.is_identical_to(context)); 1334 // The variable or constant context slot should always be in
1335 if (((attributes & READ_ONLY) == 0) || 1335 // the function context or the arguments object.
1336 context->get(index)->IsTheHole()) { 1336 if (holder->IsContext()) {
1337 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();
1338 } 1348 }
1339 } else { 1349 } else {
1340 // 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.
1341 // function context or the global object of a global context. 1351 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1342 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1343 RETURN_IF_EMPTY_HANDLE( 1352 RETURN_IF_EMPTY_HANDLE(
1344 isolate, 1353 isolate,
1345 SetProperty(object, name, initial_value, mode, kNonStrictMode)); 1354 SetProperty(context_ext, name, initial_value,
1355 mode, kNonStrictMode));
1346 } 1356 }
1347 } 1357 }
1348 1358
1349 } else { 1359 } else {
1350 // 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
1351 // "declared" in the function context's extension context or as a 1361 // "declared" in the function context's extension context, or in the
1352 // property of the the global object. 1362 // global context.
1353 Handle<JSObject> object; 1363 Handle<JSObject> context_ext;
1354 if (context->has_extension()) { 1364 if (context->has_extension()) {
1355 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()));
1356 } else { 1367 } else {
1357 // Context extension objects are allocated lazily. 1368 // The function context's extension context does not exists - allocate
1358 ASSERT(context->IsFunctionContext()); 1369 // it.
1359 object = isolate->factory()->NewJSObject( 1370 context_ext = isolate->factory()->NewJSObject(
1360 isolate->context_extension_function()); 1371 isolate->context_extension_function());
1361 context->set_extension(*object); 1372 // And store it in the extension slot.
1373 context->set_extension(*context_ext);
1362 } 1374 }
1363 ASSERT(*object != NULL); 1375 ASSERT(*context_ext != NULL);
1364 1376
1365 // 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,
1366 // 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
1367 // constant declarations). 1379 // constant declarations).
1368 ASSERT(!object->HasLocalProperty(*name)); 1380 ASSERT(!context_ext->HasLocalProperty(*name));
1369 Handle<Object> value(isolate->heap()->undefined_value(), isolate); 1381 Handle<Object> value(isolate->heap()->undefined_value(), isolate);
1370 if (*initial_value != NULL) value = initial_value; 1382 if (*initial_value != NULL) value = initial_value;
1371 // Declaring a const context slot is a conflicting declaration if 1383 // Declaring a const context slot is a conflicting declaration if
1372 // 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
1373 // allowed to introduce const variables in 1385 // allowed to introduce const variables in
1374 // JSContextExtensionObjects. They are treated specially in 1386 // JSContextExtensionObjects. They are treated specially in
1375 // SetProperty and no setters are invoked for those since they are 1387 // SetProperty and no setters are invoked for those since they are
1376 // not real JSObjects. 1388 // not real JSObjects.
1377 if (initial_value->IsTheHole() && 1389 if (initial_value->IsTheHole() &&
1378 !object->IsJSContextExtensionObject()) { 1390 !context_ext->IsJSContextExtensionObject()) {
1379 LookupResult lookup; 1391 LookupResult lookup;
1380 object->Lookup(*name, &lookup); 1392 context_ext->Lookup(*name, &lookup);
1381 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { 1393 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
1382 return ThrowRedeclarationError(isolate, "const", name); 1394 return ThrowRedeclarationError(isolate, "const", name);
1383 } 1395 }
1384 } 1396 }
1385 RETURN_IF_EMPTY_HANDLE(isolate, 1397 RETURN_IF_EMPTY_HANDLE(isolate,
1386 SetProperty(object, name, value, mode, 1398 SetProperty(context_ext, name, value, mode,
1387 kNonStrictMode)); 1399 kNonStrictMode));
1388 } 1400 }
1389 1401
1390 return isolate->heap()->undefined_value(); 1402 return isolate->heap()->undefined_value();
1391 } 1403 }
1392 1404
1393 1405
1394 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { 1406 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
1395 NoHandleAllocation nha; 1407 NoHandleAllocation nha;
1396 // args[0] == name 1408 // args[0] == name
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 return *value; 1586 return *value;
1575 } 1587 }
1576 1588
1577 1589
1578 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { 1590 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1579 HandleScope scope(isolate); 1591 HandleScope scope(isolate);
1580 ASSERT(args.length() == 3); 1592 ASSERT(args.length() == 3);
1581 1593
1582 Handle<Object> value(args[0], isolate); 1594 Handle<Object> value(args[0], isolate);
1583 ASSERT(!value->IsTheHole()); 1595 ASSERT(!value->IsTheHole());
1596 CONVERT_ARG_CHECKED(Context, context, 1);
1597 Handle<String> name(String::cast(args[2]));
1584 1598
1585 // Initializations are always done in a function or global context. 1599 // Initializations are always done in a function or global context.
1586 RUNTIME_ASSERT(args[1]->IsContext()); 1600 context = Handle<Context>(context->declaration_context());
1587 Handle<Context> context(Context::cast(args[1])->declaration_context());
1588
1589 Handle<String> name(String::cast(args[2]));
1590 1601
1591 int index; 1602 int index;
1592 PropertyAttributes attributes; 1603 PropertyAttributes attributes;
1593 ContextLookupFlags flags = FOLLOW_CHAINS; 1604 ContextLookupFlags flags = FOLLOW_CHAINS;
1594 BindingFlags binding_flags; 1605 BindingFlags binding_flags;
1595 Handle<Object> holder = 1606 Handle<Object> holder =
1596 context->Lookup(name, flags, &index, &attributes, &binding_flags); 1607 context->Lookup(name, flags, &index, &attributes, &binding_flags);
1597 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'.
1598 if (index >= 0) { 1621 if (index >= 0) {
1599 ASSERT(holder->IsContext()); 1622 if (holder->IsContext()) {
1600 // Property was found in a context. Perform the assignment if we 1623 // Property was found in a context. Perform the assignment if we
1601 // found some non-constant or an uninitialized constant. 1624 // found some non-constant or an uninitialized constant.
1602 Handle<Context> context = Handle<Context>::cast(holder); 1625 Handle<Context> context = Handle<Context>::cast(holder);
1603 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) { 1626 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1604 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));
1605 } 1636 }
1606 return *value; 1637 return *value;
1607 } 1638 }
1608 1639
1609 // 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
1610 // global object. 1641 // context.
1611 if (attributes == ABSENT) { 1642 if (attributes == ABSENT) {
1612 Handle<JSObject> global = Handle<JSObject>( 1643 Handle<JSObject> global = Handle<JSObject>(
1613 isolate->context()->global()); 1644 isolate->context()->global());
1614 // Strict mode not needed (const disallowed in strict mode). 1645 // Strict mode not needed (const disallowed in strict mode).
1615 RETURN_IF_EMPTY_HANDLE( 1646 RETURN_IF_EMPTY_HANDLE(
1616 isolate, 1647 isolate,
1617 SetProperty(global, name, value, NONE, kNonStrictMode)); 1648 SetProperty(global, name, value, NONE, kNonStrictMode));
1618 return *value; 1649 return *value;
1619 } 1650 }
1620 1651
1621 // The property was present in some function's context extension object, 1652 // The property was present in a context extension object.
1622 // 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);
1623 // object.
1624 //
1625 // In most situations, eval-introduced consts should still be present in
1626 // the context extension object. However, because declaration and
1627 // initialization are separate, the property might have been deleted
1628 // before we reach the initialization point.
1629 //
1630 // Example:
1631 //
1632 // function f() { eval("delete x; const x;"); }
1633 //
1634 // In that case, the initialization behaves like a normal assignment.
1635 Handle<JSObject> object = Handle<JSObject>::cast(holder);
1636 1654
1637 if (*object == context->extension()) { 1655 if (*context_ext == context->extension()) {
1638 // This is the property that was introduced by the const declaration. 1656 // This is the property that was introduced by the const
1639 // 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
1640 // 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.
1641 LookupResult lookup; 1660 LookupResult lookup;
1642 object->LocalLookupRealNamedProperty(*name, &lookup); 1661 context_ext->LocalLookupRealNamedProperty(*name, &lookup);
1643 ASSERT(lookup.IsProperty()); // the property was declared 1662 ASSERT(lookup.IsProperty()); // the property was declared
1644 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only 1663 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
1645 1664
1646 PropertyType type = lookup.type(); 1665 PropertyType type = lookup.type();
1647 if (type == FIELD) { 1666 if (type == FIELD) {
1648 FixedArray* properties = object->properties(); 1667 FixedArray* properties = context_ext->properties();
1649 int index = lookup.GetFieldIndex(); 1668 int index = lookup.GetFieldIndex();
1650 if (properties->get(index)->IsTheHole()) { 1669 if (properties->get(index)->IsTheHole()) {
1651 properties->set(index, *value); 1670 properties->set(index, *value);
1652 } 1671 }
1653 } else if (type == NORMAL) { 1672 } else if (type == NORMAL) {
1654 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { 1673 if (context_ext->GetNormalizedProperty(&lookup)->IsTheHole()) {
1655 object->SetNormalizedProperty(&lookup, *value); 1674 context_ext->SetNormalizedProperty(&lookup, *value);
1656 } 1675 }
1657 } else { 1676 } else {
1658 // We should not reach here. Any real, named property should be 1677 // We should not reach here. Any real, named property should be
1659 // either a field or a dictionary slot. 1678 // either a field or a dictionary slot.
1660 UNREACHABLE(); 1679 UNREACHABLE();
1661 } 1680 }
1662 } else { 1681 } else {
1663 // 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.
1664 // read-only property. 1683 // Set it if it is not a read-only property.
1665 if ((attributes & READ_ONLY) == 0) { 1684 if ((attributes & READ_ONLY) == 0) {
1666 // Strict mode not needed (const disallowed in strict mode). 1685 // Strict mode not needed (const disallowed in strict mode).
1667 RETURN_IF_EMPTY_HANDLE( 1686 RETURN_IF_EMPTY_HANDLE(
1668 isolate, 1687 isolate,
1669 SetProperty(object, name, value, attributes, kNonStrictMode)); 1688 SetProperty(context_ext, name, value, attributes, kNonStrictMode));
1670 } 1689 }
1671 } 1690 }
1672 1691
1673 return *value; 1692 return *value;
1674 } 1693 }
1675 1694
1676 1695
1677 RUNTIME_FUNCTION(MaybeObject*, 1696 RUNTIME_FUNCTION(MaybeObject*,
1678 Runtime_OptimizeObjectForAddingMultipleProperties) { 1697 Runtime_OptimizeObjectForAddingMultipleProperties) {
1679 HandleScope scope(isolate); 1698 HandleScope scope(isolate);
(...skipping 6857 matching lines...) Expand 10 before | Expand all | Expand 10 after
8537 if (holder.is_null()) { 8556 if (holder.is_null()) {
8538 return isolate->heap()->true_value(); 8557 return isolate->heap()->true_value();
8539 } 8558 }
8540 8559
8541 // 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.
8542 if (holder->IsContext()) { 8561 if (holder->IsContext()) {
8543 return isolate->heap()->false_value(); 8562 return isolate->heap()->false_value();
8544 } 8563 }
8545 8564
8546 // 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,
8547 // 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
8548 // (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.
8549 Handle<JSObject> object = Handle<JSObject>::cast(holder); 8572 Handle<JSObject> object = Handle<JSObject>::cast(holder);
8550 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 }
8551 } 8578 }
8552 8579
8553 8580
8554 // 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).
8555 // How this is achieved is calling convention-dependent. 8582 // How this is achieved is calling convention-dependent.
8556 // All currently supported x86 compiles uses calling conventions that are cdecl 8583 // All currently supported x86 compiles uses calling conventions that are cdecl
8557 // 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
8558 // (edx:eax on ia32, r1:r0 on ARM). 8585 // (edx:eax on ia32, r1:r0 on ARM).
8559 // 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.
8560 // 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
8625 int index; 8652 int index;
8626 PropertyAttributes attributes; 8653 PropertyAttributes attributes;
8627 ContextLookupFlags flags = FOLLOW_CHAINS; 8654 ContextLookupFlags flags = FOLLOW_CHAINS;
8628 BindingFlags binding_flags; 8655 BindingFlags binding_flags;
8629 Handle<Object> holder = context->Lookup(name, 8656 Handle<Object> holder = context->Lookup(name,
8630 flags, 8657 flags,
8631 &index, 8658 &index,
8632 &attributes, 8659 &attributes,
8633 &binding_flags); 8660 &binding_flags);
8634 8661
8635 // 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.
8636 if (index >= 0) { 8665 if (index >= 0) {
8637 ASSERT(holder->IsContext()); 8666 // If the "property" we were looking for is a local variable or an
8638 // If the "property" we were looking for is a local variable, the 8667 // argument in a context, the receiver is the global object; see
8639 // 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.
8640 // 8669 //
8641 // 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
8642 // and that the global receiver should be used (as distinguished from an 8671 // implicit and that the global receiver should be used.
8643 // explicit receiver that happens to be a global object).
8644 Handle<Object> receiver = isolate->factory()->the_hole_value(); 8672 Handle<Object> receiver = isolate->factory()->the_hole_value();
8645 Object* value = Context::cast(*holder)->get(index); 8673 MaybeObject* value = (holder->IsContext())
8674 ? Context::cast(*holder)->get(index)
8675 : JSObject::cast(*holder)->GetElement(index);
8646 // Check for uninitialized bindings. 8676 // Check for uninitialized bindings.
8647 if (binding_flags == MUTABLE_CHECK_INITIALIZED && value->IsTheHole()) { 8677 if (holder->IsContext() &&
8678 binding_flags == MUTABLE_CHECK_INITIALIZED &&
8679 value->IsTheHole()) {
8648 Handle<Object> reference_error = 8680 Handle<Object> reference_error =
8649 isolate->factory()->NewReferenceError("not_defined", 8681 isolate->factory()->NewReferenceError("not_defined",
8650 HandleVector(&name, 1)); 8682 HandleVector(&name, 1));
8651 return MakePair(isolate->Throw(*reference_error), NULL); 8683 return MakePair(isolate->Throw(*reference_error), NULL);
8652 } else { 8684 } else {
8653 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); 8685 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8654 } 8686 }
8655 } 8687 }
8656 8688
8657 // Otherwise, if the slot was found the holder is a context extension 8689 // If the holder is found, we read the property from it.
8658 // object, subject of a with, or a global object. We read the named 8690 if (!holder.is_null() && holder->IsJSObject()) {
8659 // property from it. 8691 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
8660 if (!holder.is_null()) {
8661 JSObject* object = JSObject::cast(*holder); 8692 JSObject* object = JSObject::cast(*holder);
8662 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
8663 // GetProperty below can cause GC. 8704 // GetProperty below can cause GC.
8664 Handle<Object> receiver_handle(object->IsGlobalObject() 8705 Handle<Object> receiver_handle(receiver);
8665 ? GlobalObject::cast(object)->global_receiver()
8666 : ComputeReceiverForNonGlobal(isolate, object));
8667 8706
8668 // 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
8669 // GetProperty function. 8708 // GetProperty function.
8670 MaybeObject* value = object->GetProperty(*name); 8709 MaybeObject* value = object->GetProperty(*name);
8671 return MakePair(value, *receiver_handle); 8710 return MakePair(value, *receiver_handle);
8672 } 8711 }
8673 8712
8674 if (throw_error) { 8713 if (throw_error) {
8675 // The property doesn't exist - throw exception. 8714 // The property doesn't exist - throw exception.
8676 Handle<Object> reference_error = 8715 Handle<Object> reference_error =
8677 isolate->factory()->NewReferenceError("not_defined", 8716 isolate->factory()->NewReferenceError("not_defined",
8678 HandleVector(&name, 1)); 8717 HandleVector(&name, 1));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8711 PropertyAttributes attributes; 8750 PropertyAttributes attributes;
8712 ContextLookupFlags flags = FOLLOW_CHAINS; 8751 ContextLookupFlags flags = FOLLOW_CHAINS;
8713 BindingFlags binding_flags; 8752 BindingFlags binding_flags;
8714 Handle<Object> holder = context->Lookup(name, 8753 Handle<Object> holder = context->Lookup(name,
8715 flags, 8754 flags,
8716 &index, 8755 &index,
8717 &attributes, 8756 &attributes,
8718 &binding_flags); 8757 &binding_flags);
8719 8758
8720 if (index >= 0) { 8759 if (index >= 0) {
8721 // The property was found in a context slot. 8760 if (holder->IsContext()) {
8722 Handle<Context> context = Handle<Context>::cast(holder); 8761 Handle<Context> context = Handle<Context>::cast(holder);
8723 if (binding_flags == MUTABLE_CHECK_INITIALIZED && 8762 if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
8724 context->get(index)->IsTheHole()) { 8763 context->get(index)->IsTheHole()) {
8725 Handle<Object> error = 8764 Handle<Object> error =
8726 isolate->factory()->NewReferenceError("not_defined", 8765 isolate->factory()->NewReferenceError("not_defined",
8727 HandleVector(&name, 1)); 8766 HandleVector(&name, 1));
8728 return isolate->Throw(*error); 8767 return isolate->Throw(*error);
8729 } 8768 }
8730 // Ignore if read_only variable. 8769 // Ignore if read_only variable.
8731 if ((attributes & READ_ONLY) == 0) { 8770 if ((attributes & READ_ONLY) == 0) {
8732 // Context is a fixed array and set cannot fail. 8771 // Context is a fixed array and set cannot fail.
8733 context->set(index, *value); 8772 context->set(index, *value);
8734 } else if (strict_mode == kStrictMode) { 8773 } else if (strict_mode == kStrictMode) {
8735 // Setting read only property in strict mode. 8774 // Setting read only property in strict mode.
8736 Handle<Object> error = 8775 Handle<Object> error =
8737 isolate->factory()->NewTypeError("strict_cannot_assign", 8776 isolate->factory()->NewTypeError("strict_cannot_assign",
8738 HandleVector(&name, 1)); 8777 HandleVector(&name, 1));
8739 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 }
8740 } 8788 }
8741 return *value; 8789 return *value;
8742 } 8790 }
8743 8791
8744 // 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.
8745 // 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.
8746 // property of the global object. 8794 Handle<JSObject> context_ext;
8747 Handle<JSObject> object;
8748 8795
8749 if (!holder.is_null()) { 8796 if (!holder.is_null()) {
8750 // The property exists on the holder. 8797 // The property exists in the extension context.
8751 object = Handle<JSObject>::cast(holder); 8798 context_ext = Handle<JSObject>::cast(holder);
8752 } else { 8799 } else {
8753 // The property was not found. 8800 // The property was not found.
8754 ASSERT(attributes == ABSENT); 8801 ASSERT(attributes == ABSENT);
8755 8802
8756 if (strict_mode == kStrictMode) { 8803 if (strict_mode == kStrictMode) {
8757 // Throw in strict mode (assignment to undefined variable). 8804 // Throw in strict mode (assignment to undefined variable).
8758 Handle<Object> error = 8805 Handle<Object> error =
8759 isolate->factory()->NewReferenceError( 8806 isolate->factory()->NewReferenceError(
8760 "not_defined", HandleVector(&name, 1)); 8807 "not_defined", HandleVector(&name, 1));
8761 return isolate->Throw(*error); 8808 return isolate->Throw(*error);
8762 } 8809 }
8763 // 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.
8764 attributes = NONE; 8811 attributes = NONE;
8765 object = Handle<JSObject>(isolate->context()->global()); 8812 context_ext = Handle<JSObject>(isolate->context()->global());
8766 } 8813 }
8767 8814
8768 // 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.
8769 if ((attributes & READ_ONLY) == 0 || 8817 if ((attributes & READ_ONLY) == 0 ||
8770 (object->GetLocalPropertyAttribute(*name) == ABSENT)) { 8818 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
8771 RETURN_IF_EMPTY_HANDLE( 8819 RETURN_IF_EMPTY_HANDLE(
8772 isolate, 8820 isolate,
8773 SetProperty(object, name, value, NONE, strict_mode)); 8821 SetProperty(context_ext, name, value, NONE, strict_mode));
8774 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { 8822 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) {
8775 // Setting read only property in strict mode. 8823 // Setting read only property in strict mode.
8776 Handle<Object> error = 8824 Handle<Object> error =
8777 isolate->factory()->NewTypeError( 8825 isolate->factory()->NewTypeError(
8778 "strict_cannot_assign", HandleVector(&name, 1)); 8826 "strict_cannot_assign", HandleVector(&name, 1));
8779 return isolate->Throw(*error); 8827 return isolate->Throw(*error);
8780 } 8828 }
8781 return *value; 8829 return *value;
8782 } 8830 }
8783 8831
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
9168 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 9216 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
9169 ASSERT(Context::cast(frame->context()) == *context); 9217 ASSERT(Context::cast(frame->context()) == *context);
9170 #endif 9218 #endif
9171 9219
9172 // 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
9173 // it is bound in the global context. 9221 // it is bound in the global context.
9174 int index = -1; 9222 int index = -1;
9175 PropertyAttributes attributes = ABSENT; 9223 PropertyAttributes attributes = ABSENT;
9176 BindingFlags binding_flags; 9224 BindingFlags binding_flags;
9177 while (true) { 9225 while (true) {
9178 // Don't follow context chains in Context::Lookup and implement the loop
9179 // up the context chain here, so that we can know the context where eval
9180 // was found.
9181 receiver = context->Lookup(isolate->factory()->eval_symbol(), 9226 receiver = context->Lookup(isolate->factory()->eval_symbol(),
9182 FOLLOW_PROTOTYPE_CHAIN, 9227 FOLLOW_PROTOTYPE_CHAIN,
9183 &index, 9228 &index,
9184 &attributes, 9229 &attributes,
9185 &binding_flags); 9230 &binding_flags);
9186 // 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
9187 // reached. 9232 // reached.
9188 if (attributes != ABSENT || context->IsGlobalContext()) break; 9233 if (attributes != ABSENT || context->IsGlobalContext()) break;
9189 context = Handle<Context>(context->previous(), isolate); 9234 context = Handle<Context>(context->previous(), isolate);
9190 } 9235 }
(...skipping 3908 matching lines...) Expand 10 before | Expand all | Expand 10 after
13099 } else { 13144 } else {
13100 // Handle last resort GC and make sure to allow future allocations 13145 // Handle last resort GC and make sure to allow future allocations
13101 // to grow the heap without causing GCs (if possible). 13146 // to grow the heap without causing GCs (if possible).
13102 isolate->counters()->gc_last_resort_from_js()->Increment(); 13147 isolate->counters()->gc_last_resort_from_js()->Increment();
13103 isolate->heap()->CollectAllGarbage(false); 13148 isolate->heap()->CollectAllGarbage(false);
13104 } 13149 }
13105 } 13150 }
13106 13151
13107 13152
13108 } } // 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