JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase()); if (!thisObj->d()->argumentsObject) thisObj->d()->argumentsObject = thisObj->createArgumentsObject(exec); return thisObj->d()->argumentsObject; }
JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identifier&) { JSActivation* activation = asActivation(slotBase); CallFrame* callFrame = CallFrame::create(activation->d()->registers); int argumentsRegister = activation->d()->functionExecutable->generatedBytecode().argumentsRegister(); if (!callFrame->uncheckedR(argumentsRegister).jsValue()) { JSValue arguments = JSValue(new (callFrame) Arguments(callFrame)); callFrame->uncheckedR(argumentsRegister) = arguments; callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = arguments; } ASSERT(callFrame->uncheckedR(argumentsRegister).jsValue().inherits(&Arguments::info)); return callFrame->uncheckedR(argumentsRegister).jsValue(); }
void JSActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { JSActivation* thisObject = jsCast<JSActivation*>(cell); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject)); if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode())) return; // We don't call through to JSObject because __proto__ and getter/setter // properties are non-standard extensions that other implementations do not // expose in the activation object. ASSERT(!thisObject->hasGetterSetterProperties()); thisObject->putOwnDataProperty(exec->vm(), propertyName, value, slot); }
void JSActivation::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { JSActivation* thisObject = static_cast<JSActivation*>(cell); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject)); if (thisObject->symbolTablePut(exec->globalData(), propertyName, value)) return; // We don't call through to JSObject because __proto__ and getter/setter // properties are non-standard extensions that other implementations do not // expose in the activation object. ASSERT(!thisObject->hasGetterSetterProperties()); thisObject->putDirect(exec->globalData(), propertyName, value, 0, true, slot); }
// FIXME: Make this function honor ReadOnly (const) and DontEnum void JSActivation::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes) { JSActivation* thisObject = jsCast<JSActivation*>(object); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject)); if (thisObject->symbolTablePutWithAttributes(exec->globalData(), propertyName, value, attributes)) return; // We don't call through to JSObject because __proto__ and getter/setter // properties are non-standard extensions that other implementations do not // expose in the activation object. ASSERT(!thisObject->hasGetterSetterProperties()); JSObject::putDirectVirtual(thisObject, exec, propertyName, value, attributes); }
void JSActivation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSActivation* thisObject = jsCast<JSActivation*>(object); SymbolTable::const_iterator end = thisObject->symbolTable().end(); for (SymbolTable::const_iterator it = thisObject->symbolTable().begin(); it != end; ++it) { if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties) continue; if (it->second.getIndex() >= thisObject->m_numCapturedVars) continue; propertyNames.add(Identifier(exec, it->first.get())); } // Skip the JSVariableObject implementation of getOwnPropertyNames JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); }
void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSActivation* thisObject = jsCast<JSActivation*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); // No need to mark our registers if they're still in the JSStack. if (!thisObject->isTornOff()) return; for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i) visitor.append(&thisObject->storage()[i]); }
bool JSActivation::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSActivation* thisObject = jsCast<JSActivation*>(object); if (propertyName == exec->propertyNames().arguments) { // Defend against the inspector asking for the arguments object after it has been optimized out. if (!thisObject->isTornOff()) { slot.setCustom(thisObject, DontEnum, thisObject->getArgumentsGetter()); return true; } } if (thisObject->symbolTableGet(propertyName, slot)) return true; unsigned attributes; if (JSValue value = thisObject->getDirect(exec->vm(), propertyName, attributes)) { slot.setValue(thisObject, attributes, value); return true; } // We don't call through to JSObject because there's no way to give an // activation object getter properties or a prototype. ASSERT(!thisObject->hasGetterSetterProperties()); ASSERT(thisObject->prototype().isNull()); return false; }
void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSActivation* thisObject = static_cast<JSActivation*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); // No need to mark our registers if they're still in the RegisterFile. WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get(); if (!registerArray) return; visitor.appendValues(registerArray, thisObject->m_numParametersMinusThis); // Skip the call frame, which sits between the parameters and vars. visitor.appendValues(registerArray + thisObject->m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize, thisObject->m_numCapturedVars); }
void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSActivation* thisObject = jsCast<JSActivation*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); // No need to mark our registers if they're still in the RegisterFile. WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get(); if (!registerArray) return; visitor.appendValues(registerArray, thisObject->m_numCapturedArgs); // Skip 'this' and call frame. visitor.appendValues(registerArray + CallFrame::offsetFor(thisObject->m_numCapturedArgs + 1), thisObject->m_numCapturedVars); }
JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, PropertyName) { JSActivation* activation = jsCast<JSActivation*>(slotBase); if (activation->isTornOff()) return jsUndefined(); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers)); int argumentsRegister = callFrame->codeBlock()->argumentsRegister(); if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue()) return arguments; int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister); JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame)); callFrame->uncheckedR(argumentsRegister) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info())); return callFrame->uncheckedR(realArgumentsRegister).jsValue(); }
bool JSActivation::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) { JSActivation* thisObject = jsCast<JSActivation*>(object); if (propertyName == exec->propertyNames().arguments) { // Defend against the inspector asking for the arguments object after it has been optimized out. if (!thisObject->isTornOff()) { PropertySlot slot(thisObject); JSActivation::getOwnPropertySlot(thisObject, exec, propertyName, slot); descriptor.setDescriptor(slot.getValue(exec, propertyName), DontEnum); return true; } } if (thisObject->symbolTableGet(propertyName, descriptor)) return true; return Base::getOwnPropertyDescriptor(object, exec, propertyName, descriptor); }
EncodedJSValue JSActivation::argumentsGetter(ExecState*, EncodedJSValue slotBase, EncodedJSValue, PropertyName) { JSActivation* activation = jsCast<JSActivation*>(JSValue::decode(slotBase)); CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers)); ASSERT(!activation->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())); if (activation->isTornOff() || !(callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) return JSValue::encode(jsUndefined()); VirtualRegister argumentsRegister = callFrame->codeBlock()->argumentsRegister(); if (JSValue arguments = callFrame->uncheckedR(argumentsRegister.offset()).jsValue()) return JSValue::encode(arguments); int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister).offset(); JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame)); callFrame->uncheckedR(argumentsRegister.offset()) = arguments; callFrame->uncheckedR(realArgumentsRegister) = arguments; ASSERT(callFrame->uncheckedR(realArgumentsRegister).jsValue().inherits(Arguments::info())); return JSValue::encode(callFrame->uncheckedR(realArgumentsRegister).jsValue()); }
JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSActivation* activation = asActivation(slot.slotBase()); if (activation->d()->functionExecutable->usesArguments()) { PropertySlot slot; activation->symbolTableGet(exec->propertyNames().arguments, slot); return slot.getValue(exec, exec->propertyNames().arguments); } CallFrame* callFrame = CallFrame::create(activation->d()->registers); Arguments* arguments = callFrame->optionalCalleeArguments(); if (!arguments) { arguments = new (callFrame) Arguments(callFrame); arguments->copyRegisters(); callFrame->setCalleeArguments(arguments); } ASSERT(arguments->inherits(&Arguments::info)); return arguments; }
void JSActivation::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSActivation* thisObject = jsCast<JSActivation*>(object); if (mode == IncludeDontEnumProperties && !thisObject->isTornOff()) propertyNames.add(exec->propertyNames().arguments); { ConcurrentJITLocker locker(thisObject->symbolTable()->m_lock); SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker); for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) { if (it->value.getAttributes() & DontEnum && mode != IncludeDontEnumProperties) continue; if (!thisObject->isValid(it->value)) continue; propertyNames.add(Identifier(exec, it->key.get())); } } // Skip the JSVariableObject implementation of getOwnNonIndexPropertyNames JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode); }
bool JSActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { JSActivation* thisObject = static_cast<JSActivation*>(cell); if (propertyName == exec->propertyNames().arguments) { slot.setCustom(thisObject, thisObject->getArgumentsGetter()); return true; } if (thisObject->symbolTableGet(propertyName, slot)) return true; if (WriteBarrierBase<Unknown>* location = thisObject->getDirectLocation(exec->globalData(), propertyName)) { slot.setValue(location->get()); return true; } // We don't call through to JSObject because there's no way to give an // activation object getter properties or a prototype. ASSERT(!thisObject->hasGetterSetterProperties()); ASSERT(thisObject->prototype().isNull()); return false; }