diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index a61038398dde4a2caf40b949197f3c2fbf4108b5..f08437879c14b51ad6a7612af12b931ef584947c 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -10,6 +10,7 @@ #include "v8-primitive.h" #include "v8-statistics.h" #include "v8-version-string.h" +#include "v8-proxy.h" #define JSVM_EXPERIMENTAL #include "env-inl.h" #include "jsvm.h" @@ -1505,6 +1506,59 @@ OH_JSVM_DestroyVM(JSVM_VM vm) { return JSVM_OK; } +JSVM_Status JSVM_CDECL OH_JSVM_CreateProxy(JSVM_Env env, JSVM_Value target, JSVM_Value handler, JSVM_Value *result) +{ + // Check args is not null + JSVM_PREAMBLE(env); + CHECK_ARG(env, target); + CHECK_ARG(env, handler); + CHECK_ARG(env, result); + + // Check target and handler are v8 Object + auto localTarget = v8impl::V8LocalValueFromJsValue(target); + RETURN_STATUS_IF_FALSE(env, localTarget->IsObject(), JSVM_OBJECT_EXPECTED); + auto localHandler = v8impl::V8LocalValueFromJsValue(handler); + RETURN_STATUS_IF_FALSE(env, localHandler->IsObject(), JSVM_OBJECT_EXPECTED); + + v8::Local context = env->context(); + + v8::MaybeLocal maybeProxy = + v8::Proxy::New(context, localTarget.As(), localHandler.As()); + + CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybeProxy, JSVM_GENERIC_FAILURE); + + v8::Local proxy = maybeProxy.ToLocalChecked(); + *result = v8impl::JsValueFromV8LocalValue(proxy); + + return jsvm_clear_last_error(env); +} + +JSVM_Status JSVM_CDECL OH_JSVM_IsProxy(JSVM_Env env, JSVM_Value value, bool *isProxy) +{ + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, isProxy); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + *isProxy = val->IsProxy(); + + return jsvm_clear_last_error(env); +} + +JSVM_Status JSVM_CDECL OH_JSVM_ProxyGetTarget(JSVM_Env env, JSVM_Value value, JSVM_Value *result) +{ + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local val = v8impl::V8LocalValueFromJsValue(value); + + RETURN_STATUS_IF_FALSE(env, val->IsProxy(), JSVM_INVALID_TYPE); + + *result = v8impl::JsValueFromV8LocalValue(val.As()->GetTarget()); + return jsvm_clear_last_error(env); +} + JSVM_Status JSVM_CDECL OH_JSVM_OpenVMScope(JSVM_VM vm, JSVM_VMScope* result) { auto isolate = reinterpret_cast(vm); auto scope = new v8::Isolate::Scope(isolate); @@ -2120,6 +2174,7 @@ static const char* error_messages[] = { "Main thread would deadlock", "External buffers are not allowed", "Cannot run JavaScript", + "Invalid type" }; JSVM_Status JSVM_CDECL OH_JSVM_GetLastErrorInfo( @@ -2131,7 +2186,7 @@ JSVM_Status JSVM_CDECL OH_JSVM_GetLastErrorInfo( // message in the `JSVM_Status` enum each time a new error message is added. // We don't have a jsvm_status_last as this would result in an ABI // change each time a message was added. - const int last_status = JSVM_CANNOT_RUN_JS; + const int last_status = JSVM_INVALID_TYPE; static_assert(JSVM_ARRAYSIZE(error_messages) == last_status + 1, "Count of error messages must match count of error values"); diff --git a/src/jsvm.h b/src/jsvm.h index 41a7f81f32df13a16233bcaffd4f2f419929a7ea..dfd53cdd51c10fc0ca20d2df5753accb279fff32 100644 --- a/src/jsvm.h +++ b/src/jsvm.h @@ -127,6 +127,61 @@ JSVM_EXTERN JSVM_Status OH_JSVM_CreateVM(const JSVM_CreateVMOptions* options, */ JSVM_EXTERN JSVM_Status OH_JSVM_DestroyVM(JSVM_VM vm); +/** + * @brief This API allocates a default JavaScript Proxy. It is the equivalent of + * doing new Proxy(target, handler) in JavaScript. + * + * @param env The environment that the API is invoked under. + * @param target A JSVM_Value representing the JavaScript Object which you want to proxy. + * @param handler A JSVM_Value representing the JavaScript Object that defines which + * operations will be intercepted and how to redefine intercepted operations. + * @param result A JSVM_Value representing a JavaScript Proxy. + * @return Returns JSVM functions result code. + * {@link JSVM_OK } if the API succeeded. \n + * {@link JSVM_INVALID_ARG } if the any of the input arguments is NULL. \n + * {@link JSVM_OBJECT_EXPECTED} if target or handler is not Javascript Object. \n + * {@link JSVM_PENDING_EXCEPTION} if an exception occurs. \n + * + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_CreateProxy(JSVM_Env env, + JSVM_Value target, + JSVM_Value handler, + JSVM_Value* result); + +/** + * @brief This API checks if the value passed in is a Proxy. + * + * @param env The environment that the API is invoked under. + * @param value The JavaScript value to check. + * @param isProxy Whether the given value is Proxy. + * @return Returns JSVM functions result code. + * {@link JSVM_OK } if the API succeeded. \n + * {@link JSVM_INVALID_ARG } if the any of the input arguments is NULL. \n + * + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_IsProxy(JSVM_Env env, + JSVM_Value value, + bool* isProxy); + +/** + * @brief This API gets target from proxy. + * + * @param env The environment that the API is invoked under. + * @param value JSVM_Value representing JavaScript Proxy whose target to return. + * @param result Target of the given proxy. + * @return Returns JSVM functions result code. + * {@link JSVM_OK } if the API succeeded. \n + * {@link JSVM_INVALID_ARG } if the any of the input arguments is NULL. \n + * {@link JSVM_INVALID_TYPE} if value is not a Javascript Proxy. \n + * + * @since 16 + */ +JSVM_EXTERN JSVM_Status OH_JSVM_ProxyGetTarget(JSVM_Env env, + JSVM_Value value, + JSVM_Value* result); + /** * @brief This API open a new VM scope for the VM instance. * diff --git a/src/jsvm_types.h b/src/jsvm_types.h index 139fec1b6568546217b6b611ca6f6ef18d8d163e..3a59a85cf953330f4c4a59f283deb07995b63f62 100644 --- a/src/jsvm_types.h +++ b/src/jsvm_types.h @@ -322,6 +322,8 @@ typedef enum { JSVM_NO_EXTERNAL_BUFFERS_ALLOWED, /** cannot run +js status. */ JSVM_CANNOT_RUN_JS, + /** invalid input type status. */ + JSVM_INVALID_TYPE } JSVM_Status; /**