Changeset 245514 in webkit
- Timestamp:
- May 20, 2019 6:48:04 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/glib/JSCCallbackFunction.cpp
r243283 r245514 208 208 case G_TYPE_OBJECT: 209 209 if (auto* ptr = returnValue.data[0].v_pointer) 210 return toRef(jscClassGetOrCreateJSWrapper(m_class.get(), ptr));210 return toRef(jscClassGetOrCreateJSWrapper(m_class.get(), context.get(), ptr)); 211 211 *exception = toRef(JSC::createTypeError(toJS(jsContext), "constructor returned null"_s)); 212 212 break; -
trunk/Source/JavaScriptCore/API/glib/JSCClass.cpp
r243289 r245514 57 57 58 58 typedef struct _JSCClassPrivate { 59 JS CContext*context;59 JSGlobalContextRef context; 60 60 CString name; 61 61 JSClassRef jsClass; … … 64 64 JSCClass* parentClass; 65 65 JSC::Weak<JSC::JSObject> prototype; 66 HashMap<CString, JSC::Weak<JSC::JSObject>> constructors;67 66 } JSCClassPrivate; 68 67 … … 284 283 285 284 switch (propID) { 286 case PROP_CONTEXT:287 g_value_set_object(value, jscClass->priv->context);288 break;289 285 case PROP_NAME: 290 286 g_value_set_string(value, jscClass->priv->name.data()); … … 304 300 switch (propID) { 305 301 case PROP_CONTEXT: 306 jscClass->priv->context = JSC_CONTEXT(g_value_get_object(value));302 jscClass->priv->context = jscContextGetJSContext(JSC_CONTEXT(g_value_get_object(value))); 307 303 break; 308 304 case PROP_NAME: … … 348 344 "JSC Context", 349 345 JSC_TYPE_CONTEXT, 350 static_cast<GParamFlags>(WEBKIT_PARAM_ READWRITE | G_PARAM_CONSTRUCT_ONLY)));346 static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))); 351 347 352 348 /** … … 493 489 prototypeDefinition.className = prototypeName.get(); 494 490 JSClassRef prototypeClass = JSClassCreate(&prototypeDefinition); 495 priv->prototype = jscContextGetOrCreateJSWrapper( priv->context, prototypeClass);491 priv->prototype = jscContextGetOrCreateJSWrapper(context, prototypeClass); 496 492 JSClassRelease(prototypeClass); 497 493 498 494 if (priv->parentClass) 499 JSObjectSetPrototype(jscContextGetJSContext( priv->context), toRef(priv->prototype.get()), toRef(priv->parentClass->priv->prototype.get()));495 JSObjectSetPrototype(jscContextGetJSContext(context), toRef(priv->prototype.get()), toRef(priv->parentClass->priv->prototype.get())); 500 496 return jscClass; 501 497 } … … 506 502 } 507 503 508 JSC::JSObject* jscClassGetOrCreateJSWrapper(JSCClass* jscClass, gpointer wrappedObject)504 JSC::JSObject* jscClassGetOrCreateJSWrapper(JSCClass* jscClass, JSCContext* context, gpointer wrappedObject) 509 505 { 510 506 JSCClassPrivate* priv = jscClass->priv; 511 return jscContextGetOrCreateJSWrapper( priv->context, priv->jsClass, toRef(priv->prototype.get()), wrappedObject, priv->destroyFunction);512 } 513 514 JSGlobalContextRef jscClassCreateContextWithJSWrapper(JSCClass* jscClass, gpointer wrappedObject)507 return jscContextGetOrCreateJSWrapper(context, priv->jsClass, toRef(priv->prototype.get()), wrappedObject, priv->destroyFunction); 508 } 509 510 JSGlobalContextRef jscClassCreateContextWithJSWrapper(JSCClass* jscClass, JSCContext* context, gpointer wrappedObject) 515 511 { 516 512 JSCClassPrivate* priv = jscClass->priv; 517 return jscContextCreateContextWithJSWrapper( priv->context, priv->jsClass, toRef(priv->prototype.get()), wrappedObject, priv->destroyFunction);513 return jscContextCreateContextWithJSWrapper(context, priv->jsClass, toRef(priv->prototype.get()), wrappedObject, priv->destroyFunction); 518 514 } 519 515 … … 563 559 closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 564 560 JSCClassPrivate* priv = jscClass->priv; 565 JSC::ExecState* exec = toJS( jscContextGetJSContext(priv->context));561 JSC::ExecState* exec = toJS(priv->context); 566 562 JSC::VM& vm = exec->vm(); 567 563 JSC::JSLockHolder locker(vm); 568 564 auto* functionObject = JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), String::fromUTF8(name), 569 565 JSC::JSCCallbackFunction::Type::Constructor, jscClass, WTFMove(closure), returnType, WTFMove(parameters)); 570 auto constructor = jscContextGetOrCreateValue(priv->context, toRef(functionObject)); 571 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(priv->context, toRef(priv->prototype.get())); 566 auto context = jscContextGetOrCreate(priv->context); 567 auto constructor = jscContextGetOrCreateValue(context.get(), toRef(functionObject)); 568 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(context.get(), toRef(priv->prototype.get())); 572 569 auto nonEnumerable = static_cast<JSCValuePropertyFlags>(JSC_VALUE_PROPERTY_CONFIGURABLE | JSC_VALUE_PROPERTY_WRITABLE); 573 570 jsc_value_object_define_property_data(constructor.get(), "prototype", nonEnumerable, prototype.get()); 574 571 jsc_value_object_define_property_data(prototype.get(), "constructor", nonEnumerable, constructor.get()); 575 priv->constructors.set(name, functionObject);576 572 return constructor; 577 573 } … … 712 708 JSCClassPrivate* priv = jscClass->priv; 713 709 GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 714 JSC::ExecState* exec = toJS( jscContextGetJSContext(priv->context));710 JSC::ExecState* exec = toJS(priv->context); 715 711 JSC::VM& vm = exec->vm(); 716 712 JSC::JSLockHolder locker(vm); 717 713 auto* functionObject = toRef(JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), String::fromUTF8(name), 718 714 JSC::JSCCallbackFunction::Type::Method, jscClass, WTFMove(closure), returnType, WTFMove(parameters))); 719 auto method = jscContextGetOrCreateValue(priv->context, functionObject); 720 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(priv->context, toRef(priv->prototype.get())); 715 auto context = jscContextGetOrCreate(priv->context); 716 auto method = jscContextGetOrCreateValue(context.get(), functionObject); 717 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(context.get(), toRef(priv->prototype.get())); 721 718 auto nonEnumerable = static_cast<JSCValuePropertyFlags>(JSC_VALUE_PROPERTY_CONFIGURABLE | JSC_VALUE_PROPERTY_WRITABLE); 722 719 jsc_value_object_define_property_data(prototype.get(), name, nonEnumerable, method.get()); … … 863 860 g_return_if_fail(priv->context); 864 861 865 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(priv->context, toRef(priv->prototype.get())); 862 auto context = jscContextGetOrCreate(priv->context); 863 GRefPtr<JSCValue> prototype = jscContextGetOrCreateValue(context.get(), toRef(priv->prototype.get())); 866 864 jsc_value_object_define_property_accessor(prototype.get(), name, JSC_VALUE_PROPERTY_CONFIGURABLE, propertyType, getter, setter, userData, destroyNotify); 867 865 } -
trunk/Source/JavaScriptCore/API/glib/JSCClassPrivate.h
r234025 r245514 28 28 GRefPtr<JSCClass> jscClassCreate(JSCContext*, const char*, JSCClass*, JSCClassVTable*, GDestroyNotify); 29 29 JSClassRef jscClassGetJSClass(JSCClass*); 30 JSC::JSObject* jscClassGetOrCreateJSWrapper(JSCClass*, gpointer);31 JSGlobalContextRef jscClassCreateContextWithJSWrapper(JSCClass*, gpointer);30 JSC::JSObject* jscClassGetOrCreateJSWrapper(JSCClass*, JSCContext*, gpointer); 31 JSGlobalContextRef jscClassCreateContextWithJSWrapper(JSCClass*, JSCContext*, gpointer); 32 32 void jscClassInvalidate(JSCClass*); -
trunk/Source/JavaScriptCore/API/glib/JSCContext.cpp
r239569 r245514 879 879 880 880 JSRetainPtr<JSGlobalContextRef> objectContext(Adopt, 881 instance ? jscClassCreateContextWithJSWrapper(objectClass, instance) : JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(context->priv->vm.get()), nullptr));881 instance ? jscClassCreateContextWithJSWrapper(objectClass, context, instance) : JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(context->priv->vm.get()), nullptr)); 882 882 JSC::ExecState* exec = toJS(objectContext.get()); 883 883 JSC::VM& vm = exec->vm(); -
trunk/Source/JavaScriptCore/API/glib/JSCValue.cpp
r243289 r245514 603 603 g_return_val_if_fail(!instance || JSC_IS_CLASS(jscClass), nullptr); 604 604 605 return jscContextGetOrCreateValue(context, instance ? toRef(jscClassGetOrCreateJSWrapper(jscClass, instance)) : JSObjectMake(jscContextGetJSContext(context), nullptr, nullptr)).leakRef();605 return jscContextGetOrCreateValue(context, instance ? toRef(jscClassGetOrCreateJSWrapper(jscClass, context, instance)) : JSObjectMake(jscContextGetJSContext(context), nullptr, nullptr)).leakRef(); 606 606 } 607 607 -
trunk/Source/JavaScriptCore/ChangeLog
r245511 r245514 1 2019-05-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GLIB] Crash when instantiating a js object registered with jsc_context_register_class on window object cleared 4 https://bugs.webkit.org/show_bug.cgi?id=198037 5 6 Reviewed by Michael Catanzaro. 7 8 This happens because JSCClass is keeping a pointer to the JSCContext used when the class is registered, and the 9 context can be destroyed before the class. We can't a reference to the context, because we don't really want to 10 keep it alive. The life of the JSCClass is not attached to the JSCContext, but to its wrapped global context, so 11 we can keep a pointer to the JSGlobalContextRef instead and create a new JSCContext wrapping it when 12 needed. This patch is also making the context property of JSCClass non-readable, which was always the intention, 13 that's why there isn't a public getter in the API. 14 15 * API/glib/JSCCallbackFunction.cpp: 16 (JSC::JSCCallbackFunction::construct): Pass the context to jscClassGetOrCreateJSWrapper(). 17 * API/glib/JSCClass.cpp: 18 (jscClassGetProperty): Remove the getter for context property. 19 (jscClassSetProperty): Get the JSGlobalContextRef from the given JSCContext. 20 (jsc_class_class_init): Make context writable only. 21 (jscClassCreate): Use the passed in context instead of the member. 22 (jscClassGetOrCreateJSWrapper): It receives now the context as parameter. 23 (jscClassCreateContextWithJSWrapper): Ditto. 24 (jscClassCreateConstructor): Get or create a JSCContext for our JSGlobalContextRef. 25 (jscClassAddMethod): Ditto. 26 (jsc_class_add_property): Ditto. 27 * API/glib/JSCClassPrivate.h: 28 * API/glib/JSCContext.cpp: 29 (jsc_context_evaluate_in_object): Pass the context to jscClassCreateContextWithJSWrapper(). 30 * API/glib/JSCValue.cpp: 31 (jsc_value_new_object): Pass the context to jscClassGetOrCreateJSWrapper(). 32 1 33 2019-05-19 Tadeu Zagallo <tzagallo@apple.com> 2 34 -
trunk/Tools/ChangeLog
r245512 r245514 1 2019-05-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GLIB] Crash when instantiating a js object registered with jsc_context_register_class on window object cleared 4 https://bugs.webkit.org/show_bug.cgi?id=198037 5 6 Reviewed by Michael Catanzaro. 7 8 Add a test case to check the crash is fixed. 9 10 * TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp: 11 (testWebExtensionWindowObjectCleared): 12 * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp: 13 (windowObjectCleared): 14 1 15 2019-05-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 16 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebExtensions.cpp
r239772 r245514 180 180 GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); 181 181 g_assert_cmpstr(valueString.get(), ==, "Foo"); 182 183 javascriptResult = test->runJavaScriptAndWaitUntilFinished("var f = new GFile('.'); f.path();", &error.outPtr()); 184 g_assert_nonnull(javascriptResult); 185 g_assert_no_error(error.get()); 186 valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); 187 GUniquePtr<char> currentDirectory(g_get_current_dir()); 188 g_assert_cmpstr(valueString.get(), ==, currentDirectory.get()); 182 189 } 183 190 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp
r245176 r245514 428 428 GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function(jsContext.get(), "echo", G_CALLBACK(echoCallback), NULL, NULL, G_TYPE_STRING, 1, G_TYPE_STRING)); 429 429 jsc_context_set_value(jsContext.get(), "echo", function.get()); 430 431 auto* fileClass = jsc_context_register_class(jsContext.get(), "GFile", nullptr, nullptr, static_cast<GDestroyNotify>(g_object_unref)); 432 GRefPtr<JSCValue> constructor = adoptGRef(jsc_class_add_constructor(fileClass, "GFile", G_CALLBACK(g_file_new_for_path), nullptr, nullptr, G_TYPE_OBJECT, 1, G_TYPE_STRING)); 433 jsc_class_add_method(fileClass, "path", G_CALLBACK(g_file_get_path), nullptr, nullptr, G_TYPE_STRING, 0, G_TYPE_NONE); 434 jsc_context_set_value(jsContext.get(), "GFile", constructor.get()); 430 435 } 431 436
Note: See TracChangeset
for help on using the changeset viewer.