Changeset 231693 in webkit
- Timestamp:
- May 10, 2018 11:56:57 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/glib/JSCClass.cpp
r231565 r231693 522 522 } 523 523 524 /** 525 * jsc_class_add_constructor: 526 * @jsc_class: a #JSCClass 527 * @name: (nullable): the constructor name or %NULL 528 * @callback: (scope async): a #GCallback to be called to create an instance of @jsc_class 529 * @user_data: (closure): user data to pass to @callback 530 * @destroy_notify: (nullable): destroy notifier for @user_data 531 * @return_type: the #GType of the constructor return value 532 * @n_params: the number of parameter types to follow or 0 if constructor doesn't receive parameters. 533 * @...: a list of #GType<!-- -->s, one for each parameter. 534 * 535 * Add a constructor to @jsc_class. If @name is %NULL, the class name will be used. When <function>new</function> 536 * is used with the constructor or jsc_value_constructor_call() is called, @callback is invoked receiving the 537 * parameters and @user_data as the last parameter. When the constructor object is cleared in the #JSCClass context, 538 * @destroy_notify is called with @user_data as parameter. 539 * 540 * This function creates the constructor, that needs to be added to an object as a property to be able to use it. Use 541 * jsc_context_set_value() to make the constructor available in the global object. 542 * 543 * Returns: (transfer full): a #JSCValue representing the class constructor. 544 */ 545 JSCValue* jsc_class_add_constructor(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned paramCount, ...) 546 { 547 g_return_val_if_fail(JSC_IS_CLASS(jscClass), nullptr); 548 g_return_val_if_fail(callback, nullptr); 549 524 static GRefPtr<JSCValue> jscClassCreateConstructor(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters) 525 { 550 526 JSCClassPrivate* priv = jscClass->priv; 551 g_return_val_if_fail(priv->context, nullptr);552 553 if (!name)554 name = priv->name.data();555 556 va_list args;557 va_start(args, paramCount);558 Vector<GType> parameters;559 if (paramCount) {560 parameters.reserveInitialCapacity(paramCount);561 for (unsigned i = 0; i < paramCount; ++i)562 parameters.uncheckedAppend(va_arg(args, GType));563 }564 va_end(args);565 566 527 GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 567 528 JSC::ExecState* exec = toJS(jscContextGetJSContext(priv->context)); … … 576 537 jsc_value_object_define_property_data(prototype.get(), "constructor", nonEnumerable, constructor.get()); 577 538 priv->constructors.set(name, functionObject); 578 return constructor .leakRef();579 } 580 581 /** 582 * jsc_class_add_ method:583 * @jsc_class: a #JSCClass 584 * @name: the method name585 * @callback: (scope async): a #GCallback to be called to invoke method @name of @jsc_class539 return constructor; 540 } 541 542 /** 543 * jsc_class_add_constructor: (skip) 544 * @jsc_class: a #JSCClass 545 * @name: (nullable): the constructor name or %NULL 546 * @callback: (scope async): a #GCallback to be called to create an instance of @jsc_class 586 547 * @user_data: (closure): user data to pass to @callback 587 548 * @destroy_notify: (nullable): destroy notifier for @user_data 588 * @return_type: the #GType of the method return value, or %G_TYPE_NONE if the method is void.589 * @n_params: the number of parameter types to follow or 0 if the methoddoesn't receive parameters.549 * @return_type: the #GType of the constructor return value 550 * @n_params: the number of parameter types to follow or 0 if constructor doesn't receive parameters. 590 551 * @...: a list of #GType<!-- -->s, one for each parameter. 591 552 * 592 * Add method with @name to @jsc_class. When the method is called by JavaScript or jsc_value_object_invoke_method(), 593 * @callback is called receiving the class instance as first parameter, followed by the method parameters and then 594 * @user_data as last parameter. When the method is cleared in the #JSCClass context, @destroy_notify is called with 595 * @user_data as parameter. 596 */ 597 void jsc_class_add_method(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned paramCount, ...) 598 { 599 g_return_if_fail(JSC_IS_CLASS(jscClass)); 600 g_return_if_fail(name); 601 g_return_if_fail(callback); 553 * Add a constructor to @jsc_class. If @name is %NULL, the class name will be used. When <function>new</function> 554 * is used with the constructor or jsc_value_constructor_call() is called, @callback is invoked receiving the 555 * parameters and @user_data as the last parameter. When the constructor object is cleared in the #JSCClass context, 556 * @destroy_notify is called with @user_data as parameter. 557 * 558 * This function creates the constructor, that needs to be added to an object as a property to be able to use it. Use 559 * jsc_context_set_value() to make the constructor available in the global object. 560 * 561 * Returns: (transfer full): a #JSCValue representing the class constructor. 562 */ 563 JSCValue* jsc_class_add_constructor(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned paramCount, ...) 564 { 565 g_return_val_if_fail(JSC_IS_CLASS(jscClass), nullptr); 566 g_return_val_if_fail(callback, nullptr); 602 567 603 568 JSCClassPrivate* priv = jscClass->priv; 604 g_return_if_fail(priv->context); 569 g_return_val_if_fail(priv->context, nullptr); 570 571 if (!name) 572 name = priv->name.data(); 605 573 606 574 va_list args; … … 614 582 va_end(args); 615 583 584 return jscClassCreateConstructor(jscClass, name ? name : priv->name.data(), callback, userData, destroyNotify, returnType, WTFMove(parameters)).leakRef(); 585 586 } 587 588 /** 589 * jsc_class_add_constructorv: (rename-to jsc_class_add_constructor) 590 * @jsc_class: a #JSCClass 591 * @name: (nullable): the constructor name or %NULL 592 * @callback: (scope async): a #GCallback to be called to create an instance of @jsc_class 593 * @user_data: (closure): user data to pass to @callback 594 * @destroy_notify: (nullable): destroy notifier for @user_data 595 * @return_type: the #GType of the constructor return value 596 * @n_parameters: the number of parameters 597 * @parameter_types: (nullable) (array length=n_parameters) (element-type GType): a list of #GType<!-- -->s, one for each parameter, or %NULL 598 * 599 * Add a constructor to @jsc_class. If @name is %NULL, the class name will be used. When <function>new</function> 600 * is used with the constructor or jsc_value_constructor_call() is called, @callback is invoked receiving the 601 * parameters and @user_data as the last parameter. When the constructor object is cleared in the #JSCClass context, 602 * @destroy_notify is called with @user_data as parameter. 603 * 604 * This function creates the constructor, that needs to be added to an object as a property to be able to use it. Use 605 * jsc_context_set_value() to make the constructor available in the global object. 606 * 607 * Returns: (transfer full): a #JSCValue representing the class constructor. 608 */ 609 JSCValue* jsc_class_add_constructorv(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned parametersCount, GType* parameterTypes) 610 { 611 g_return_val_if_fail(JSC_IS_CLASS(jscClass), nullptr); 612 g_return_val_if_fail(callback, nullptr); 613 g_return_val_if_fail(!parametersCount || parameterTypes, nullptr); 614 615 JSCClassPrivate* priv = jscClass->priv; 616 g_return_val_if_fail(priv->context, nullptr); 617 618 if (!name) 619 name = priv->name.data(); 620 621 Vector<GType> parameters; 622 if (parametersCount) { 623 parameters.reserveInitialCapacity(parametersCount); 624 for (unsigned i = 0; i < parametersCount; ++i) 625 parameters.uncheckedAppend(parameterTypes[i]); 626 } 627 628 return jscClassCreateConstructor(jscClass, name ? name : priv->name.data(), callback, userData, destroyNotify, returnType, WTFMove(parameters)).leakRef(); 629 } 630 631 static void jscClassAddMethod(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters) 632 { 633 JSCClassPrivate* priv = jscClass->priv; 616 634 GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 617 635 JSC::ExecState* exec = toJS(jscContextGetJSContext(priv->context)); … … 627 645 628 646 /** 647 * jsc_class_add_method: (skip) 648 * @jsc_class: a #JSCClass 649 * @name: the method name 650 * @callback: (scope async): a #GCallback to be called to invoke method @name of @jsc_class 651 * @user_data: (closure): user data to pass to @callback 652 * @destroy_notify: (nullable): destroy notifier for @user_data 653 * @return_type: the #GType of the method return value, or %G_TYPE_NONE if the method is void. 654 * @n_params: the number of parameter types to follow or 0 if the method doesn't receive parameters. 655 * @...: a list of #GType<!-- -->s, one for each parameter. 656 * 657 * Add method with @name to @jsc_class. When the method is called by JavaScript or jsc_value_object_invoke_method(), 658 * @callback is called receiving the class instance as first parameter, followed by the method parameters and then 659 * @user_data as last parameter. When the method is cleared in the #JSCClass context, @destroy_notify is called with 660 * @user_data as parameter. 661 */ 662 void jsc_class_add_method(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned paramCount, ...) 663 { 664 g_return_if_fail(JSC_IS_CLASS(jscClass)); 665 g_return_if_fail(name); 666 g_return_if_fail(callback); 667 g_return_if_fail(jscClass->priv->context); 668 669 va_list args; 670 va_start(args, paramCount); 671 Vector<GType> parameters; 672 if (paramCount) { 673 parameters.reserveInitialCapacity(paramCount); 674 for (unsigned i = 0; i < paramCount; ++i) 675 parameters.uncheckedAppend(va_arg(args, GType)); 676 } 677 va_end(args); 678 679 jscClassAddMethod(jscClass, name, callback, userData, destroyNotify, returnType, WTFMove(parameters)); 680 } 681 682 /** 683 * jsc_class_add_methodv: (rename-to jsc_class_add_method) 684 * @jsc_class: a #JSCClass 685 * @name: the method name 686 * @callback: (scope async): a #GCallback to be called to invoke method @name of @jsc_class 687 * @user_data: (closure): user data to pass to @callback 688 * @destroy_notify: (nullable): destroy notifier for @user_data 689 * @return_type: the #GType of the method return value, or %G_TYPE_NONE if the method is void. 690 * @n_parameters: the number of parameter types to follow or 0 if the method doesn't receive parameters. 691 * @parameter_types: (nullable) (array length=n_parameters) (element-type GType): a list of #GType<!-- -->s, one for each parameter, or %NULL 692 * 693 * Add method with @name to @jsc_class. When the method is called by JavaScript or jsc_value_object_invoke_method(), 694 * @callback is called receiving the class instance as first parameter, followed by the method parameters and then 695 * @user_data as last parameter. When the method is cleared in the #JSCClass context, @destroy_notify is called with 696 * @user_data as parameter. 697 */ 698 void jsc_class_add_methodv(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned parametersCount, GType *parameterTypes) 699 { 700 g_return_if_fail(JSC_IS_CLASS(jscClass)); 701 g_return_if_fail(name); 702 g_return_if_fail(callback); 703 g_return_if_fail(!parametersCount || parameterTypes); 704 g_return_if_fail(jscClass->priv->context); 705 706 Vector<GType> parameters; 707 if (parametersCount) { 708 parameters.reserveInitialCapacity(parametersCount); 709 for (unsigned i = 0; i < parametersCount; ++i) 710 parameters.uncheckedAppend(parameterTypes[i]); 711 } 712 713 jscClassAddMethod(jscClass, name, callback, userData, destroyNotify, returnType, WTFMove(parameters)); 714 } 715 716 /** 629 717 * jsc_class_add_property: 630 718 * @jsc_class: a #JSCClass -
trunk/Source/JavaScriptCore/API/glib/JSCClass.h
r230753 r231693 77 77 78 78 JSC_API GType 79 jsc_class_get_type (void);79 jsc_class_get_type (void); 80 80 81 81 JSC_API const char * 82 jsc_class_get_name (JSCClass *jsc_class);82 jsc_class_get_name (JSCClass *jsc_class); 83 83 84 84 JSC_API JSCClass * 85 jsc_class_get_parent (JSCClass *jsc_class);85 jsc_class_get_parent (JSCClass *jsc_class); 86 86 87 87 JSC_API JSCValue * 88 jsc_class_add_constructor (JSCClass *jsc_class, 89 const char *name, 90 GCallback callback, 91 gpointer user_data, 92 GDestroyNotify destroy_notify, 93 GType return_type, 94 unsigned n_params, 95 ...); 88 jsc_class_add_constructor (JSCClass *jsc_class, 89 const char *name, 90 GCallback callback, 91 gpointer user_data, 92 GDestroyNotify destroy_notify, 93 GType return_type, 94 guint n_params, 95 ...); 96 97 JSC_API JSCValue * 98 jsc_class_add_constructorv (JSCClass *jsc_class, 99 const char *name, 100 GCallback callback, 101 gpointer user_data, 102 GDestroyNotify destroy_notify, 103 GType return_type, 104 guint n_parameters, 105 GType *parameter_types); 96 106 97 107 JSC_API void 98 jsc_class_add_method (JSCClass *jsc_class,99 const char *name,100 GCallback callback,101 gpointer user_data,102 GDestroyNotify destroy_notify,103 GType return_type,104 unsignedn_params,105 ...);108 jsc_class_add_method (JSCClass *jsc_class, 109 const char *name, 110 GCallback callback, 111 gpointer user_data, 112 GDestroyNotify destroy_notify, 113 GType return_type, 114 guint n_params, 115 ...); 106 116 107 117 JSC_API void 108 jsc_class_add_property (JSCClass *jsc_class, 109 const char *name, 110 GType property_type, 111 GCallback getter, 112 GCallback setter, 113 gpointer user_data, 114 GDestroyNotify destroy_notify); 118 jsc_class_add_methodv (JSCClass *jsc_class, 119 const char *name, 120 GCallback callback, 121 gpointer user_data, 122 GDestroyNotify destroy_notify, 123 GType return_type, 124 guint n_parameters, 125 GType *parameter_types); 126 127 JSC_API void 128 jsc_class_add_property (JSCClass *jsc_class, 129 const char *name, 130 GType property_type, 131 GCallback getter, 132 GCallback setter, 133 gpointer user_data, 134 GDestroyNotify destroy_notify); 115 135 116 136 G_END_DECLS -
trunk/Source/JavaScriptCore/API/glib/JSCValue.cpp
r231565 r231693 458 458 459 459 /** 460 * jsc_value_new_array: 460 * jsc_value_new_array: (skip) 461 461 * @context: a #JSCContext 462 462 * @first_item_type: #GType of first item, or %G_TYPE_NONE … … 832 832 } 833 833 834 static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, const Vector<JSValueRef>& arguments, JSValueRef* exception) 835 { 836 switch (functionType) { 837 case JSC::JSCCallbackFunction::Type::Constructor: 838 return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), exception); 839 break; 840 case JSC::JSCCallbackFunction::Type::Method: 841 ASSERT(thisObject); 842 FALLTHROUGH; 843 case JSC::JSCCallbackFunction::Type::Function: 844 return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), exception); 845 break; 846 } 847 RELEASE_ASSERT_NOT_REACHED(); 848 } 849 834 850 static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, GType firstParameterType, va_list args) 835 851 { … … 859 875 } 860 876 861 JSValueRef result; 862 switch (functionType) { 863 case JSC::JSCCallbackFunction::Type::Constructor: 864 result = JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), &exception); 865 break; 866 case JSC::JSCCallbackFunction::Type::Method: 867 ASSERT(thisObject); 868 FALLTHROUGH; 869 case JSC::JSCCallbackFunction::Type::Function: 870 result = JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), &exception); 871 break; 872 } 877 auto result = jsObjectCall(jsContext, function, functionType, thisObject, arguments, &exception); 873 878 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 874 879 return adoptGRef(jsc_value_new_undefined(priv->context.get())); … … 878 883 879 884 /** 880 * jsc_value_object_invoke_method: 885 * jsc_value_object_invoke_method: (skip) 881 886 * @value: a #JSCValue 882 887 * @name: the method name … … 922 927 923 928 return result.leakRef(); 929 } 930 931 /** 932 * jsc_value_object_invoke_methodv: (rename-to jsc_value_object_invoke_method) 933 * @value: a #JSCValue 934 * @name: the method name 935 * @n_parameters: the number of parameters 936 * @parameters: (nullable) (array length=n_parameters) (element-type JSCValue): the #JSCValue<!-- -->s to pass as parameters to the method, or %NULL 937 * 938 * Invoke method with @name on object referenced by @value, passing the given @parameters. If 939 * @n_parameters is 0 no parameters will be passed to the method. 940 * The object instance will be handled automatically even when the method is a custom one 941 * registered with jsc_class_add_method(), so it should never be passed explicitly as parameter 942 * of this function. 943 * 944 * This function always returns a #JSCValue, in case of void methods a #JSCValue referencing 945 * <function>undefined</function> is returned. 946 * 947 * Returns: (transfer full): a #JSCValue with the return value of the method. 948 */ 949 JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, unsigned parametersCount, JSCValue** parameters) 950 { 951 g_return_val_if_fail(JSC_IS_VALUE(value), nullptr); 952 g_return_val_if_fail(name, nullptr); 953 g_return_val_if_fail(!parametersCount || parameters, nullptr); 954 955 JSCValuePrivate* priv = value->priv; 956 auto* jsContext = jscContextGetJSContext(priv->context.get()); 957 JSValueRef exception = nullptr; 958 JSObjectRef object = JSValueToObject(jsContext, priv->jsValue, &exception); 959 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 960 return jsc_value_new_undefined(priv->context.get()); 961 962 JSRetainPtr<JSStringRef> methodName(Adopt, JSStringCreateWithUTF8CString(name)); 963 JSValueRef functionValue = JSObjectGetProperty(jsContext, object, methodName.get(), &exception); 964 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 965 return jsc_value_new_undefined(priv->context.get()); 966 967 JSObjectRef function = JSValueToObject(jsContext, functionValue, &exception); 968 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 969 return jsc_value_new_undefined(priv->context.get()); 970 971 Vector<JSValueRef> arguments; 972 if (parametersCount) { 973 arguments.reserveInitialCapacity(parametersCount); 974 for (unsigned i = 0; i < parametersCount; ++i) 975 arguments.uncheckedAppend(jscValueGetJSValue(parameters[i])); 976 } 977 978 auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments, &exception); 979 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 980 jsc_value_new_undefined(priv->context.get()); 981 982 return jscContextGetOrCreateValue(priv->context.get(), result).leakRef(); 924 983 } 925 984 … … 1022 1081 } 1023 1082 1024 /** 1025 * jsc_value_new_function: 1083 static GRefPtr<JSCValue> jscValueFunctionCreate(JSCContext* context, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters) 1084 { 1085 GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 1086 JSC::ExecState* exec = toJS(jscContextGetJSContext(context)); 1087 JSC::VM& vm = exec->vm(); 1088 JSC::JSLockHolder locker(vm); 1089 auto* functionObject = toRef(JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), name ? String::fromUTF8(name) : ASCIILiteral("anonymous"), 1090 JSC::JSCCallbackFunction::Type::Function, nullptr, WTFMove(closure), returnType, WTFMove(parameters))); 1091 return jscContextGetOrCreateValue(context, functionObject); 1092 } 1093 1094 /** 1095 * jsc_value_new_function: (skip) 1026 1096 * @context: a #JSCContext: 1027 1097 * @name: (nullable): the function name or %NULL … … 1055 1125 va_end(args); 1056 1126 1057 GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify)))); 1058 JSC::ExecState* exec = toJS(jscContextGetJSContext(context)); 1059 JSC::VM& vm = exec->vm(); 1060 JSC::JSLockHolder locker(vm); 1061 auto* functionObject = toRef(JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), name ? String::fromUTF8(name) : ASCIILiteral("anonymous"), 1062 JSC::JSCCallbackFunction::Type::Function, nullptr, WTFMove(closure), returnType, WTFMove(parameters))); 1063 return jscContextGetOrCreateValue(context, functionObject).leakRef(); 1127 return jscValueFunctionCreate(context, name, callback, userData, destroyNotify, returnType, WTFMove(parameters)).leakRef(); 1128 } 1129 1130 /** 1131 * jsc_value_new_functionv: (rename-to jsc_value_new_function) 1132 * @context: a #JSCContext: 1133 * @name: (nullable): the function name or %NULL 1134 * @callback: (scope async): a #GCallback. 1135 * @user_data: (closure): user data to pass to @callback. 1136 * @destroy_notify: (nullable): destroy notifier for @user_data 1137 * @return_type: the #GType of the function return value, or %G_TYPE_NONE if the function is void. 1138 * @n_parameters: the number of parameters 1139 * @parameter_types: (nullable) (array length=n_parameters) (element-type GType): a list of #GType<!-- -->s, one for each parameter, or %NULL 1140 * 1141 * Create a function in @context. If @name is %NULL an anonymous function will be created. 1142 * When the function is called by JavaScript or jsc_value_function_call(), @callback is called 1143 * receiving the function parameters and then @user_data as last parameter. When the function is 1144 * cleared in @context, @destroy_notify is called with @user_data as parameter. 1145 * 1146 * Returns: (transfer full): a #JSCValue. 1147 */ 1148 JSCValue* jsc_value_new_functionv(JSCContext* context, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, unsigned parametersCount, GType *parameterTypes) 1149 { 1150 g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr); 1151 g_return_val_if_fail(callback, nullptr); 1152 g_return_val_if_fail(!parametersCount || parameterTypes, nullptr); 1153 1154 Vector<GType> parameters; 1155 if (parametersCount) { 1156 parameters.reserveInitialCapacity(parametersCount); 1157 for (unsigned i = 0; i < parametersCount; ++i) 1158 parameters.uncheckedAppend(parameterTypes[i]); 1159 } 1160 1161 return jscValueFunctionCreate(context, name, callback, userData, destroyNotify, returnType, WTFMove(parameters)).leakRef(); 1064 1162 } 1065 1163 … … 1084 1182 1085 1183 /** 1086 * jsc_value_function_call: 1184 * jsc_value_function_call: (skip) 1087 1185 * @value: a #JSCValue 1088 1186 * @first_parameter_type: #GType of first parameter, or %G_TYPE_NONE … … 1117 1215 1118 1216 /** 1217 * jsc_value_function_callv: (rename-to jsc_value_function_call) 1218 * @value: a #JSCValue 1219 * @n_parameters: the number of parameters 1220 * @parameters: (nullable) (array length=n_parameters) (element-type JSCValue): the #JSCValue<!-- -->s to pass as parameters to the function, or %NULL 1221 * 1222 * Call function referenced by @value, passing the given @parameters. If @n_parameters 1223 * is 0 no parameters will be passed to the function. 1224 * 1225 * This function always returns a #JSCValue, in case of void functions a #JSCValue referencing 1226 * <function>undefined</function> is returned 1227 * 1228 * Returns: (transfer full): a #JSCValue with the return value of the function. 1229 */ 1230 JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JSCValue** parameters) 1231 { 1232 g_return_val_if_fail(JSC_IS_VALUE(value), nullptr); 1233 g_return_val_if_fail(!parametersCount || parameters, nullptr); 1234 1235 JSCValuePrivate* priv = value->priv; 1236 auto* jsContext = jscContextGetJSContext(priv->context.get()); 1237 JSValueRef exception = nullptr; 1238 JSObjectRef function = JSValueToObject(jsContext, priv->jsValue, &exception); 1239 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 1240 return jsc_value_new_undefined(priv->context.get()); 1241 1242 Vector<JSValueRef> arguments; 1243 if (parametersCount) { 1244 arguments.reserveInitialCapacity(parametersCount); 1245 for (unsigned i = 0; i < parametersCount; ++i) 1246 arguments.uncheckedAppend(jscValueGetJSValue(parameters[i])); 1247 } 1248 1249 auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments, &exception); 1250 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 1251 return jsc_value_new_undefined(priv->context.get()); 1252 1253 return jscContextGetOrCreateValue(priv->context.get(), result).leakRef(); 1254 } 1255 1256 /** 1119 1257 * jsc_value_is_constructor: 1120 1258 * @value: a #JSCValue … … 1136 1274 1137 1275 /** 1138 * jsc_value_constructor_call: 1276 * jsc_value_constructor_call: (skip) 1139 1277 * @value: a #JSCValue 1140 1278 * @first_parameter_type: #GType of first parameter, or %G_TYPE_NONE … … 1164 1302 return result.leakRef(); 1165 1303 } 1304 1305 /** 1306 * jsc_value_constructor_callv: (rename-to jsc_value_constructor_call) 1307 * @value: a #JSCValue 1308 * @n_parameters: the number of parameters 1309 * @parameters: (nullable) (array length=n_parameters) (element-type JSCValue): the #JSCValue<!-- -->s to pass as parameters to the constructor, or %NULL 1310 * 1311 * Invoke <function>new</function> with constructor referenced by @value. If @n_parameters 1312 * is 0 no parameters will be passed to the constructor. 1313 * 1314 * Returns: (transfer full): a #JSCValue referencing the newly created object instance. 1315 */ 1316 JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount, JSCValue** parameters) 1317 { 1318 g_return_val_if_fail(JSC_IS_VALUE(value), nullptr); 1319 g_return_val_if_fail(!parametersCount || parameters, nullptr); 1320 1321 JSCValuePrivate* priv = value->priv; 1322 auto* jsContext = jscContextGetJSContext(priv->context.get()); 1323 JSValueRef exception = nullptr; 1324 JSObjectRef function = JSValueToObject(jsContext, priv->jsValue, &exception); 1325 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 1326 return jsc_value_new_undefined(priv->context.get()); 1327 1328 Vector<JSValueRef> arguments; 1329 if (parametersCount) { 1330 arguments.reserveInitialCapacity(parametersCount); 1331 for (unsigned i = 0; i < parametersCount; ++i) 1332 arguments.uncheckedAppend(jscValueGetJSValue(parameters[i])); 1333 } 1334 1335 auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments, &exception); 1336 if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception)) 1337 return jsc_value_new_undefined(priv->context.get()); 1338 1339 return jscContextGetOrCreateValue(priv->context.get(), result).leakRef(); 1340 } -
trunk/Source/JavaScriptCore/API/glib/JSCValue.h
r230704 r231693 181 181 ...); 182 182 183 JSC_API JSCValue * 184 jsc_value_object_invoke_methodv (JSCValue *value, 185 const char *name, 186 guint n_parameters, 187 JSCValue **parameters); 188 183 189 JSC_API void 184 190 jsc_value_object_define_property_data (JSCValue *value, … … 207 213 ...); 208 214 215 JSC_API JSCValue * 216 jsc_value_new_functionv (JSCContext *context, 217 const char *name, 218 GCallback callback, 219 gpointer user_data, 220 GDestroyNotify destroy_notify, 221 GType return_type, 222 guint n_parameters, 223 GType *parameter_types); 224 209 225 JSC_API gboolean 210 226 jsc_value_is_function (JSCValue *value); … … 215 231 ...); 216 232 233 JSC_API JSCValue * 234 jsc_value_function_callv (JSCValue *value, 235 guint n_parameters, 236 JSCValue **parameters); 237 217 238 JSC_API gboolean 218 239 jsc_value_is_constructor (JSCValue *value); … … 223 244 ...); 224 245 246 JSC_API JSCValue * 247 jsc_value_constructor_callv (JSCValue *value, 248 guint n_parameters, 249 JSCValue **parameters); 250 225 251 G_END_DECLS 226 252 -
trunk/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt
r230753 r231693 93 93 jsc_value_object_enumerate_properties 94 94 jsc_value_object_invoke_method 95 jsc_value_object_invoke_methodv 95 96 jsc_value_object_define_property_data 96 97 jsc_value_object_define_property_accessor 97 98 jsc_value_new_function 99 jsc_value_new_functionv 98 100 jsc_value_is_function 99 101 jsc_value_function_call 102 jsc_value_function_callv 100 103 jsc_value_is_constructor 101 104 jsc_value_constructor_call 105 jsc_value_constructor_callv 102 106 103 107 <SUBSECTION Standard> … … 172 176 jsc_class_get_parent 173 177 jsc_class_add_constructor 178 jsc_class_add_constructorv 174 179 jsc_class_add_method 180 jsc_class_add_methodv 175 181 jsc_class_add_property 176 182 -
trunk/Source/JavaScriptCore/ChangeLog
r231688 r231693 1 2018-05-10 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [JSC][GLIB] Add introspectable alternatives to functions using vargars 4 https://bugs.webkit.org/show_bug.cgi?id=185508 5 6 Reviewed by Michael Catanzaro. 7 8 * API/glib/JSCClass.cpp: 9 (jscClassCreateConstructor): 10 (jsc_class_add_constructor): 11 (jsc_class_add_constructorv): 12 (jscClassAddMethod): 13 (jsc_class_add_method): 14 (jsc_class_add_methodv): 15 * API/glib/JSCClass.h: 16 * API/glib/JSCValue.cpp: 17 (jsObjectCall): 18 (jscValueCallFunction): 19 (jsc_value_object_invoke_methodv): 20 (jscValueFunctionCreate): 21 (jsc_value_new_function): 22 (jsc_value_new_functionv): 23 (jsc_value_function_callv): 24 (jsc_value_constructor_callv): 25 * API/glib/JSCValue.h: 26 * API/glib/docs/jsc-glib-4.0-sections.txt: 27 1 28 2018-05-10 Yusuke Suzuki <utatane.tea@gmail.com> 2 29 -
trunk/Tools/ChangeLog
r231686 r231693 1 2018-05-10 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [JSC][GLIB] Add introspectable alternatives to functions using vargars 4 https://bugs.webkit.org/show_bug.cgi?id=185508 5 6 Reviewed by Michael Catanzaro. 7 8 Add test cases for the new API. 9 10 * TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp: 11 (testJSCFunction): 12 (testJSCObject): 13 1 14 2018-05-10 Leo Balter <leonardo.balter@gmail.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
r230889 r231693 582 582 checker.watch(value.get()); 583 583 g_assert_true(value.get() == result.get()); 584 585 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref)); 586 auto* parameter = jsc_value_new_number(context.get(), 200); 587 checker.watch(parameter); 588 g_ptr_array_add(parameters.get(), parameter); 589 value = adoptGRef(jsc_value_function_callv(function.get(), parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 590 checker.watch(value.get()); 591 g_assert_true(value.get() == result.get()); 592 } 593 594 { 595 LeakChecker checker; 596 GRefPtr<JSCContext> context = adoptGRef(jsc_context_new()); 597 checker.watch(context.get()); 598 ExceptionHandler exceptionHandler(context.get()); 599 600 GType parameterTypes[] = { G_TYPE_INT }; 601 GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_functionv(context.get(), "foo", G_CALLBACK(foo), nullptr, nullptr, G_TYPE_INT, 1, parameterTypes)); 602 checker.watch(function.get()); 603 jsc_context_set_value(context.get(), "foo", function.get()); 604 GRefPtr<JSCValue> result = adoptGRef(jsc_context_evaluate(context.get(), "foo(200)", -1)); 605 checker.watch(result.get()); 606 g_assert_true(jsc_value_is_number(result.get())); 607 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 400); 608 609 GRefPtr<JSCValue> value = adoptGRef(jsc_value_function_call(function.get(), G_TYPE_INT, 200, G_TYPE_NONE)); 610 checker.watch(value.get()); 611 g_assert_true(value.get() == result.get()); 612 613 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref)); 614 auto* parameter = jsc_value_new_number(context.get(), 200); 615 checker.watch(parameter); 616 g_ptr_array_add(parameters.get(), parameter); 617 value = adoptGRef(jsc_value_function_callv(function.get(), parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 618 checker.watch(value.get()); 619 g_assert_true(value.get() == result.get()); 584 620 } 585 621 … … 599 635 600 636 GRefPtr<JSCValue> value = adoptGRef(jsc_value_function_call(function.get(), G_TYPE_INT, 200, G_TYPE_NONE)); 637 checker.watch(value.get()); 638 g_assert_true(value.get() == result.get()); 639 640 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref)); 641 auto* parameter = jsc_value_new_number(context.get(), 200); 642 checker.watch(parameter); 643 g_ptr_array_add(parameters.get(), parameter); 644 value = adoptGRef(jsc_value_function_callv(function.get(), parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 601 645 checker.watch(value.get()); 602 646 g_assert_true(value.get() == result.get()); … … 627 671 checker.watch(dbl.get()); 628 672 GRefPtr<JSCValue> value = adoptGRef(jsc_value_function_call(function.get(), JSC_TYPE_VALUE, dbl.get(), G_TYPE_NONE)); 673 checker.watch(value.get()); 674 result = adoptGRef(jsc_context_evaluate(context.get(), "result", -1)); 675 checker.watch(result.get()); 676 g_assert_true(jsc_value_is_number(result.get())); 677 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 400); 678 679 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new()); 680 g_ptr_array_add(parameters.get(), dbl.get()); 681 value = adoptGRef(jsc_value_function_callv(function.get(), parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 629 682 checker.watch(value.get()); 630 683 result = adoptGRef(jsc_context_evaluate(context.get(), "result", -1)); … … 716 769 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 400); 717 770 771 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref)); 772 auto* parameter = jsc_value_new_number(context.get(), 200); 773 checker.watch(parameter); 774 g_ptr_array_add(parameters.get(), parameter); 775 result = adoptGRef(jsc_value_object_invoke_methodv(foo.get(), "foo", parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 776 checker.watch(result.get()); 777 g_assert_true(jsc_value_is_number(result.get())); 778 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 400); 779 718 780 g_assert_false(jsc_value_object_has_property(foo.get(), "bar")); 719 781 bool didThrow = false; … … 724 786 g_assert_did_throw(exceptionHandler, didThrow); 725 787 788 g_assert_throw_begin(exceptionHandler, didThrow); 789 result = adoptGRef(jsc_value_object_invoke_methodv(foo.get(), "bar", parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 790 checker.watch(result.get()); 791 g_assert_true(jsc_value_is_undefined(result.get())); 792 g_assert_did_throw(exceptionHandler, didThrow); 793 726 794 GRefPtr<JSCValue> constructor = adoptGRef(jsc_context_evaluate(context.get(), "Foo", -1)); 727 795 checker.watch(constructor.get()); … … 748 816 g_assert_true(jsc_value_is_number(result.get())); 749 817 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 1000); 818 819 GRefPtr<JSCValue> foo2 = adoptGRef(jsc_value_constructor_callv(constructor.get(), 0, nullptr)); 820 checker.watch(foo2.get()); 821 g_assert_true(jsc_value_is_object(foo2.get())); 822 g_assert_true(jsc_value_object_is_instance_of(foo2.get(), "Foo")); 823 g_assert_false(foo.get() == foo2.get()); 750 824 } 751 825 … … 1183 1257 g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 0); 1184 1258 1259 value = adoptGRef(jsc_value_object_invoke_methodv(foo.get(), "getFoo", 0, nullptr)); 1260 checker.watch(value.get()); 1261 g_assert_true(jsc_value_is_number(value.get())); 1262 g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 0); 1263 1185 1264 GRefPtr<JSCValue> value2 = adoptGRef(jsc_context_evaluate(context.get(), "f.getFoo()", -1)); 1186 1265 checker.watch(value2.get()); … … 1188 1267 1189 1268 g_assert_false(jsc_value_object_has_property(foo.get(), "setFoo")); 1190 jsc_class_add_method(jscClass, "setFoo", G_CALLBACK(setFoo), nullptr, nullptr, G_TYPE_NONE, 1, G_TYPE_INT); 1269 GType parameterTypes[] = { G_TYPE_INT }; 1270 jsc_class_add_methodv(jscClass, "setFoo", G_CALLBACK(setFoo), nullptr, nullptr, G_TYPE_NONE, 1, parameterTypes); 1191 1271 g_assert_true(jsc_value_object_has_property(foo.get(), "setFoo")); 1192 1272 properties.reset(jsc_value_object_enumerate_properties(foo.get())); … … 1206 1286 g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 45); 1207 1287 1208 GRefPtr<JSCValue> constructor2 = adoptGRef(jsc_class_add_constructor(jscClass, "CreateWithFoo", G_CALLBACK(fooCreateWithFoo), nullptr, nullptr, G_TYPE_POINTER, 1, G_TYPE_INT)); 1288 value = adoptGRef(jsc_value_object_invoke_methodv(foo.get(), "getFoo", 0, nullptr)); 1289 checker.watch(value.get()); 1290 g_assert_true(jsc_value_is_number(value.get())); 1291 g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 45); 1292 1293 GRefPtr<JSCValue> constructor2 = adoptGRef(jsc_class_add_constructorv(jscClass, "CreateWithFoo", G_CALLBACK(fooCreateWithFoo), nullptr, nullptr, G_TYPE_POINTER, 1, parameterTypes)); 1209 1294 checker.watch(constructor2.get()); 1210 1295 g_assert_true(jsc_value_is_constructor(constructor2.get())); … … 1312 1397 checker.watch(jscClass); 1313 1398 1314 GRefPtr<JSCValue> constructor = adoptGRef(jsc_class_add_constructor (jscClass, nullptr, G_CALLBACK(fooCreate), nullptr, nullptr, G_TYPE_POINTER, 0, G_TYPE_NONE));1399 GRefPtr<JSCValue> constructor = adoptGRef(jsc_class_add_constructorv(jscClass, nullptr, G_CALLBACK(fooCreate), nullptr, nullptr, G_TYPE_POINTER, 0, nullptr)); 1315 1400 checker.watch(constructor.get()); 1316 1401 g_assert_true(jsc_value_is_constructor(constructor.get())); … … 1555 1640 g_assert_cmpint(jsc_value_to_int32(result.get()), ==, 42); 1556 1641 1557 GRefPtr<JSCValue> foo3 = adoptGRef(jsc_value_constructor_call(constructor2.get(), G_TYPE_INT, 62, G_TYPE_NONE)); 1642 GRefPtr<GPtrArray> parameters = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref)); 1643 auto* parameter = jsc_value_new_number(context.get(), 62); 1644 checker.watch(parameter); 1645 g_ptr_array_add(parameters.get(), parameter); 1646 1647 GRefPtr<JSCValue> foo3 = adoptGRef(jsc_value_constructor_callv(constructor2.get(), parameters->len, reinterpret_cast<JSCValue**>(parameters->pdata))); 1558 1648 checker.watch(foo3.get()); 1559 1649 g_assert_true(jsc_value_is_object(foo3.get()));
Note: See TracChangeset
for help on using the changeset viewer.