Changeset 180467 in webkit
- Timestamp:
- Feb 20, 2015 4:36:27 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSWrapperMap.mm
r180452 r180467 109 109 } 110 110 111 static JS ObjectRefmakeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)111 static JSC::JSObject* makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject) 112 112 { 113 113 JSC::ExecState* exec = toJS(ctx); … … 120 120 object->setPrototype(exec->vm(), prototype); 121 121 122 return toRef(object);122 return object; 123 123 } 124 124 … … 126 126 // other than that it has a native brand set that will be displayed by the default 127 127 // Object.prototype.toString conversion. 128 static JS Value*objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0)128 static JSC::JSObject *objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0) 129 129 { 130 130 JSClassDefinition definition; … … 132 132 definition.className = [brand UTF8String]; 133 133 JSClassRef classRef = JSClassCreate(&definition); 134 JS ObjectRefresult = makeWrapper([context JSGlobalContextRef], classRef, cls);134 JSC::JSObject* result = makeWrapper([context JSGlobalContextRef], classRef, cls); 135 135 JSClassRelease(classRef); 136 return [JSValue valueWithJSValueRef:result inContext:context];137 } 138 139 static JS Value*constructorWithCustomBrand(JSContext *context, NSString *brand, Class cls)136 return result; 137 } 138 139 static JSC::JSObject *constructorWithCustomBrand(JSContext *context, NSString *brand, Class cls) 140 140 { 141 141 JSClassDefinition definition; … … 144 144 definition.hasInstance = constructorHasInstance; 145 145 JSClassRef classRef = JSClassCreate(&definition); 146 JS ObjectRefresult = makeWrapper([context JSGlobalContextRef], classRef, cls);146 JSC::JSObject* result = makeWrapper([context JSGlobalContextRef], classRef, cls); 147 147 JSClassRelease(classRef); 148 return [JSValue valueWithJSValueRef:result inContext:context];148 return result; 149 149 } 150 150 … … 366 366 367 367 - (id)initWithContext:(JSContext *)context forClass:(Class)cls; 368 - (JS Value*)wrapperForObject:(id)object;369 - (JS Value*)constructor;368 - (JSC::JSObject *)wrapperForObject:(id)object; 369 - (JSC::JSObject *)constructor; 370 370 - (JSC::JSObject *)prototype; 371 371 … … 398 398 } 399 399 400 static JS Value *allocateConstructorForCustomClass(JSContext *context, const char* className, Class cls)400 static JSC::JSObject* allocateConstructorForCustomClass(JSContext *context, const char* className, Class cls) 401 401 { 402 402 if (!supportsInitMethodConstructors()) … … 445 445 446 446 JSObjectRef method = objCCallbackFunctionForInit(context, cls, initProtocol, initMethod, types); 447 return [JSValue valueWithJSValueRef:method inContext:context];447 return toJS(method); 448 448 } 449 449 return constructorWithCustomBrand(context, [NSString stringWithFormat:@"%sConstructor", className], cls); … … 458 458 ASSERT(!m_constructor || !m_prototype); 459 459 ASSERT((m_class == [NSObject class]) == !superClassInfo); 460 461 JSC::JSObject* jsPrototype = m_prototype.get(); 462 JSC::JSObject* jsConstructor = m_constructor.get(); 463 460 464 if (!superClassInfo) { 461 465 JSContextRef cContext = [m_context JSGlobalContextRef]; 462 466 JSValue *constructor = m_context[@"Object"]; 463 if (! m_constructor)464 m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));465 466 if (! m_prototype) {467 if (!jsConstructor) 468 jsConstructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0)); 469 470 if (!jsPrototype) { 467 471 JSValue *prototype = constructor[@"prototype"]; 468 m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));472 jsPrototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0)); 469 473 } 470 474 } else { … … 472 476 473 477 // Create or grab the prototype/constructor pair. 474 JSValue *prototype; 475 JSValue *constructor; 476 if (m_prototype) 477 prototype = [JSValue valueWithJSValueRef:toRef(m_prototype.get()) inContext:m_context]; 478 else 479 prototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]); 480 481 if (m_constructor) 482 constructor = [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context]; 483 else 484 constructor = allocateConstructorForCustomClass(m_context, className, m_class); 485 486 JSContextRef cContext = [m_context JSGlobalContextRef]; 487 m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0)); 488 m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0)); 489 478 if (!jsPrototype) 479 jsPrototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]); 480 481 if (!jsConstructor) 482 jsConstructor = allocateConstructorForCustomClass(m_context, className, m_class); 483 484 JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:m_context]; 485 JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:m_context]; 490 486 putNonEnumerable(prototype, @"constructor", constructor); 491 487 putNonEnumerable(constructor, @"prototype", prototype); … … 499 495 // Set [Prototype]. 500 496 JSC::JSObject* superClassPrototype = [superClassInfo prototype]; 501 JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(m_prototype.get()), toRef(superClassPrototype)); 502 } 503 return ConstructorPrototypePair(m_constructor.get(), m_prototype.get()); 504 } 505 506 - (JSValue *)wrapperForObject:(id)object 497 JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype)); 498 } 499 500 m_prototype = jsPrototype; 501 m_constructor = jsConstructor; 502 return ConstructorPrototypePair(jsConstructor, jsPrototype); 503 } 504 505 - (JSC::JSObject*)wrapperForObject:(id)object 507 506 { 508 507 ASSERT([object isKindOfClass:m_class]); … … 514 513 putNonEnumerable(constructor, @"prototype", prototype); 515 514 putNonEnumerable(prototype, @"constructor", constructor); 516 return constructor;515 return toJS(method); 517 516 } 518 517 } … … 520 519 JSC::JSObject* prototype = [self prototype]; 521 520 522 JS ObjectRefwrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);523 JSObjectSetPrototype([m_context JSGlobalContextRef], wrapper, toRef(prototype));524 return [JSValue valueWithJSValueRef:wrapper inContext:m_context];525 } 526 527 - (JS Value*)constructor521 JSC::JSObject* wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object); 522 JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(wrapper), toRef(prototype)); 523 return wrapper; 524 } 525 526 - (JSC::JSObject*)constructor 528 527 { 529 528 JSC::JSObject* constructor = m_constructor.get(); … … 531 530 constructor = [self allocateConstructorAndPrototype].first; 532 531 ASSERT(!!constructor); 533 return [JSValue valueWithJSValueRef:toRef(constructor) inContext:m_context];532 return constructor; 534 533 } 535 534 … … 596 595 return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; 597 596 598 JSValue *wrapper;599 597 if (class_isMetaClass(object_getClass(object))) 600 wrapper = [[self classInfoForClass:(Class)object] constructor];598 jsWrapper = [[self classInfoForClass:(Class)object] constructor]; 601 599 else { 602 600 JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]]; 603 wrapper = [classInfo wrapperForObject:object];601 jsWrapper = [classInfo wrapperForObject:object]; 604 602 } 605 603 … … 609 607 // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects, 610 608 // but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc. 611 JSC::ExecState* exec = toJS([m_context JSGlobalContextRef]);612 jsWrapper = toJS(exec, valueInternalValue(wrapper)).toObject(exec);613 609 m_cachedJSWrappers.set(object, jsWrapper); 614 return wrapper;610 return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; 615 611 } 616 612 -
trunk/Source/JavaScriptCore/ChangeLog
r180461 r180467 1 2015-02-20 Mark Lam <mark.lam@apple.com> 2 3 Refactor JSWrapperMap.mm to defer creation of the ObjC JSValue until the latest possible moment. 4 <https://webkit.org/b/141856> 5 6 Reviewed by Geoffrey Garen. 7 8 1. Make JSObjCClassInfo's -constructor and -wrapperForObject return a 9 JSC::JSObject* just like -prototype. 10 2. Defer the creation of the ObjC JSValue from JSC::JSObject* until 11 the latest moment when it is needed. This allows us to not have to 12 keep converting back to a JSC::JSObject* in intermediate code. 13 14 * API/JSWrapperMap.mm: 15 (makeWrapper): 16 (objectWithCustomBrand): 17 (constructorWithCustomBrand): 18 (allocateConstructorForCustomClass): 19 (-[JSObjCClassInfo allocateConstructorAndPrototype]): 20 (-[JSObjCClassInfo wrapperForObject:]): 21 (-[JSObjCClassInfo constructor]): 22 (-[JSWrapperMap jsWrapperForObject:]): 23 1 24 2015-02-20 Filip Pizlo <fpizlo@apple.com> 2 25
Note: See TracChangeset
for help on using the changeset viewer.