Changeset 197136 in webkit for trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp
- Timestamp:
- Feb 25, 2016, 2:58:23 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp
r197042 r197136 301 301 } 302 302 303 template <typename PerformDefaultPutFunction> 304 void ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPutFunction) 305 { 306 VM& vm = exec->vm(); 307 JSValue handlerValue = this->handler(); 308 if (handlerValue.isNull()) { 309 throwVMTypeError(exec, ASCIILiteral("Proxy 'handler' is null. It should be an Object.")); 310 return; 311 } 312 313 JSObject* handler = jsCast<JSObject*>(handlerValue); 314 CallData callData; 315 CallType callType; 316 JSValue setMethod = handler->getMethod(exec, callData, callType, vm.propertyNames->set, ASCIILiteral("'set' property of a Proxy's handler should be callable.")); 317 if (exec->hadException()) 318 return; 319 JSObject* target = this->target(); 320 if (setMethod.isUndefined()) { 321 performDefaultPutFunction(); 322 return; 323 } 324 325 MarkedArgumentBuffer arguments; 326 arguments.append(target); 327 arguments.append(identifierToSafePublicJSValue(vm, Identifier::fromUid(&vm, propertyName.uid()))); 328 arguments.append(putValue); 329 arguments.append(thisValue); 330 JSValue trapResult = call(exec, setMethod, callType, callData, handler, arguments); 331 if (exec->hadException()) 332 return; 333 bool trapResultAsBool = trapResult.toBoolean(exec); 334 if (exec->hadException()) 335 return; 336 if (!trapResultAsBool) 337 return; 338 339 PropertyDescriptor descriptor; 340 if (target->getOwnPropertyDescriptor(exec, propertyName, descriptor)) { 341 if (descriptor.isDataDescriptor() && !descriptor.configurable() && !descriptor.writable()) { 342 if (!sameValue(exec, descriptor.value(), putValue)) { 343 throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'set' on a non-configurable and non-writable property on 'target' should either return false or be the same value already on the 'target'.")); 344 return; 345 } 346 } else if (descriptor.isAccessorDescriptor() && !descriptor.configurable() && descriptor.setter().isUndefined()) { 347 throwVMTypeError(exec, ASCIILiteral("Proxy handler's 'set' method on a non-configurable accessor property without a setter should return false.")); 348 return; 349 } 350 } 351 } 352 353 void ProxyObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) 354 { 355 VM& vm = exec->vm(); 356 ProxyObject* thisObject = jsCast<ProxyObject*>(cell); 357 auto performDefaultPut = [&] () { 358 JSObject* target = jsCast<JSObject*>(thisObject->target()); 359 target->methodTable(vm)->put(target, exec, propertyName, value, slot); 360 }; 361 thisObject->performPut(exec, value, slot.thisValue(), propertyName, performDefaultPut); 362 } 363 364 void ProxyObject::putByIndexCommon(ExecState* exec, JSValue thisValue, unsigned propertyName, JSValue putValue, bool shouldThrow) 365 { 366 VM& vm = exec->vm(); 367 Identifier ident = Identifier::from(exec, propertyName); 368 if (exec->hadException()) 369 return; 370 auto performDefaultPut = [&] () { 371 JSObject* target = this->target(); 372 bool isStrictMode = shouldThrow; 373 PutPropertySlot slot(thisValue, isStrictMode); // We must preserve the "this" target of the putByIndex. 374 target->methodTable(vm)->put(target, exec, ident.impl(), putValue, slot); 375 }; 376 performPut(exec, putValue, thisValue, ident.impl(), performDefaultPut); 377 } 378 379 void ProxyObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow) 380 { 381 ProxyObject* thisObject = jsCast<ProxyObject*>(cell); 382 thisObject->putByIndexCommon(exec, thisObject, propertyName, value, shouldThrow); 383 } 384 303 385 static EncodedJSValue JSC_HOST_CALL performProxyCall(ExecState* exec) 304 386 { … … 346 428 } 347 429 348 void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor)349 {350 ProxyObject* thisObject = jsCast<ProxyObject*>(cell);351 ASSERT_GC_OBJECT_INHERITS(thisObject, info());352 Base::visitChildren(thisObject, visitor);353 354 visitor.append(&thisObject->m_target);355 visitor.append(&thisObject->m_handler);356 }357 358 430 static EncodedJSValue JSC_HOST_CALL performProxyConstruct(ExecState* exec) 359 431 { … … 477 549 } 478 550 551 void ProxyObject::visitChildren(JSCell* cell, SlotVisitor& visitor) 552 { 553 ProxyObject* thisObject = jsCast<ProxyObject*>(cell); 554 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 555 Base::visitChildren(thisObject, visitor); 556 557 visitor.append(&thisObject->m_target); 558 visitor.append(&thisObject->m_handler); 559 } 560 479 561 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.