Changeset 49726 in webkit for trunk/JavaScriptCore/interpreter/Interpreter.cpp
- Timestamp:
- Oct 16, 2009, 7:31:42 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r49717 r49726 939 939 } 940 940 941 StructureChain* protoChain = structure->prototypeChain(callFrame); 942 if (!protoChain->isCacheable()) { 943 vPC[0] = getOpcode(op_put_by_id_generic); 944 return; 945 } 946 941 947 // Structure transition, cache transition info 942 948 if (slot.type() == PutPropertySlot::NewProperty) { … … 945 951 return; 946 952 } 947 948 // put_by_id_transition checks the prototype chain for setters.949 normalizePrototypeChain(callFrame, baseCell);950 951 953 vPC[0] = getOpcode(op_put_by_id_transition); 952 954 vPC[4] = structure->previousID(); 953 955 vPC[5] = structure; 954 vPC[6] = structure->prototypeChain(callFrame);956 vPC[6] = protoChain; 955 957 vPC[7] = slot.cachedOffset(); 956 958 codeBlock->refStructures(vPC); … … 1048 1050 } 1049 1051 1050 size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase());1052 size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot); 1051 1053 if (!count) { 1052 1054 vPC[0] = getOpcode(op_get_by_id_generic); … … 1054 1056 } 1055 1057 1058 StructureChain* protoChain = structure->prototypeChain(callFrame); 1059 if (!protoChain->isCacheable()) { 1060 vPC[0] = getOpcode(op_get_by_id_generic); 1061 return; 1062 } 1063 1056 1064 vPC[0] = getOpcode(op_get_by_id_chain); 1057 1065 vPC[4] = structure; 1058 vPC[5] = structure->prototypeChain(callFrame);1066 vPC[5] = protoChain; 1059 1067 vPC[6] = count; 1060 1068 vPC[7] = slot.cachedOffset(); … … 3495 3503 } 3496 3504 DEFINE_OPCODE(op_get_pnames) { 3497 /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset)3505 /* get_pnames dst(r) base(r) 3498 3506 3499 3507 Creates a property name list for register base and puts it 3500 in register dst, initializing i and size for iteration. If 3501 base is undefined or null, jumps to breakTarget. 3508 in register dst. This is not a true JavaScript value, just 3509 a synthetic value used to keep the iteration state in a 3510 register. 3502 3511 */ 3503 3512 int dst = vPC[1].u.operand; 3504 3513 int base = vPC[2].u.operand; 3505 int i = vPC[3].u.operand; 3506 int size = vPC[4].u.operand; 3507 int breakTarget = vPC[5].u.operand; 3508 3509 JSValue v = callFrame->r(base).jsValue(); 3510 if (v.isUndefinedOrNull()) { 3511 vPC += breakTarget; 3514 3515 callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue()); 3516 vPC += OPCODE_LENGTH(op_get_pnames); 3517 NEXT_INSTRUCTION(); 3518 } 3519 DEFINE_OPCODE(op_next_pname) { 3520 /* next_pname dst(r) iter(r) target(offset) 3521 3522 Tries to copies the next name from property name list in 3523 register iter. If there are names left, then copies one to 3524 register dst, and jumps to offset target. If there are none 3525 left, invalidates the iterator and continues to the next 3526 instruction. 3527 */ 3528 int dst = vPC[1].u.operand; 3529 int iter = vPC[2].u.operand; 3530 int target = vPC[3].u.operand; 3531 3532 JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 3533 if (JSValue temp = it->next(callFrame)) { 3534 CHECK_FOR_TIMEOUT(); 3535 callFrame->r(dst) = JSValue(temp); 3536 vPC += target; 3512 3537 NEXT_INSTRUCTION(); 3513 3538 } 3514 3515 JSObject* o = v.toObject(callFrame); 3516 Structure* structure = o->structure(); 3517 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); 3518 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) 3519 jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); 3520 3521 callFrame->r(dst) = jsPropertyNameIterator; 3522 callFrame->r(base) = JSValue(o); 3523 callFrame->r(i) = Register::withInt(0); 3524 callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size()); 3525 vPC += OPCODE_LENGTH(op_get_pnames); 3526 NEXT_INSTRUCTION(); 3527 } 3528 DEFINE_OPCODE(op_next_pname) { 3529 /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) 3530 3531 Copies the next name from the property name list in 3532 register iter to dst, then jumps to offset target. If there are no 3533 names left, invalidates the iterator and continues to the next 3534 instruction. 3535 */ 3536 int dst = vPC[1].u.operand; 3537 int base = vPC[2].u.operand; 3538 int i = vPC[3].u.operand; 3539 int size = vPC[4].u.operand; 3540 int iter = vPC[5].u.operand; 3541 int target = vPC[6].u.operand; 3542 3543 JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 3544 while (callFrame->r(i).i() != callFrame->r(size).i()) { 3545 JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); 3546 callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1); 3547 if (key) { 3548 CHECK_FOR_TIMEOUT(); 3549 callFrame->r(dst) = key; 3550 vPC += target; 3551 NEXT_INSTRUCTION(); 3552 } 3553 } 3539 it->invalidate(); 3554 3540 3555 3541 vPC += OPCODE_LENGTH(op_next_pname);
Note:
See TracChangeset
for help on using the changeset viewer.