1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "jerryscript-ext/handler.h"
17 #include "jerryscript_headers.h"
18 #include "native_engine/native_value.h"
19 #include "utils/log.h"
20
21 struct jerry_external_context {
22 void* value = nullptr;
23 jerry_finalizer_t callback = nullptr;
24 void* hint = nullptr;
25 };
26
27 namespace {
__anon45ec0b610202() 28 static jerry_object_native_info_t g_objectNativeInfo = { .free_cb = [](void* nativePointer) {
29 auto externalCtx = (jerry_external_context*)nativePointer;
30 if (externalCtx != nullptr) {
31 externalCtx->callback(externalCtx->value, externalCtx->hint);
32 delete externalCtx;
33 }
34 } };
35 } // namespace
36
jerry_add_external()37 bool jerry_add_external()
38 {
39 auto callback = [](const jerry_value_t function, const jerry_value_t thisVal, const jerry_value_t args[],
40 const jerry_length_t argc) -> jerry_value_t { return jerry_create_boolean(true); };
41
42 auto constructor = jerry_create_external_function(callback);
43 auto prototype = jerry_create_object();
44
45 jerry_value_t propName = jerry_create_string_from_utf8((const jerry_char_t*)"prototype");
46 jerry_value_t resultVal = jerry_set_property(constructor, propName, prototype);
47 jerry_release_value(propName);
48
49 if (!jerry_value_to_boolean(resultVal)) {
50 HILOG_ERROR("jerry_add_external failed");
51 return false;
52 }
53
54 jerry_value_t global = jerry_get_global_object();
55 jerryx_set_property_str(global, "External", constructor);
56 jerry_release_value(global);
57 return true;
58 }
59
jerry_create_external(void * value,jerry_finalizer_t finalizer,void * hint)60 jerry_value_t jerry_create_external(void* value, jerry_finalizer_t finalizer, void* hint)
61 {
62 auto externalCtx = new jerry_external_context {
63 .value = value,
64 .callback = finalizer,
65 .hint = hint,
66 };
67 jerry_value_t global = jerry_get_global_object();
68 jerry_value_t external = jerryx_get_property_str(global, "External");
69 jerry_value_t object = jerry_create_undefined();
70
71 if (!jerry_value_is_undefined(external)) {
72 object = jerry_construct_object(external, nullptr, 0);
73 jerry_set_object_native_pointer(object, (void*)externalCtx, &g_objectNativeInfo);
74 }
75
76 jerry_release_value(external);
77 jerry_release_value(global);
78
79 return object;
80 }
81
jerry_value_is_external(const jerry_value_t object)82 bool jerry_value_is_external(const jerry_value_t object)
83 {
84 jerry_value_t global = jerry_get_global_object();
85 jerry_value_t external = jerryx_get_property_str(global, "External");
86 jerry_value_t op = jerry_create_boolean(false);
87
88 if (!jerry_value_is_undefined(external)) {
89 op = jerry_binary_operation(JERRY_BIN_OP_INSTANCEOF, object, external);
90 }
91
92 jerry_release_value(external);
93 jerry_release_value(global);
94 return jerry_get_boolean_value(op);
95 }
96
jerry_value_get_external(const jerry_value_t object)97 void* jerry_value_get_external(const jerry_value_t object)
98 {
99 jerry_external_context* externalCtx = nullptr;
100
101 jerry_get_object_native_pointer(object, (void**)&externalCtx, &g_objectNativeInfo);
102 if (externalCtx != nullptr) {
103 return externalCtx->value;
104 } else {
105 return nullptr;
106 }
107 }
108
jerry_freeze(jerry_value_t value)109 void jerry_freeze(jerry_value_t value)
110 {
111 const jerry_char_t funcResource[] = "unknown";
112 const jerry_char_t funcArgList[] = "v1 ";
113 const jerry_char_t funcSrc[] = " Object.freeze( v1 ) ";
114
115 jerry_value_t funcVal = jerry_parse_function(funcResource, sizeof(funcResource) - 1, funcArgList,
116 sizeof(funcArgList) - 1, funcSrc, sizeof(funcSrc) - 1, JERRY_PARSE_NO_OPTS);
117
118 jerry_value_t funcArgs[1] = { value };
119
120 jerry_value_t valRet = jerry_call_function(funcVal, funcArgs[0], funcArgs, 1);
121
122 jerry_release_value(valRet);
123 jerry_release_value(funcVal);
124 }
125
jerry_seal(jerry_value_t value)126 void jerry_seal(jerry_value_t value)
127 {
128 const jerry_char_t funcResource[] = "unknown";
129 const jerry_char_t funcArgList[] = "v1 ";
130 const jerry_char_t funcSrc[] = " Object.seal( v1 ) ";
131
132 jerry_value_t funcVal = jerry_parse_function(funcResource, sizeof(funcResource) - 1, funcArgList,
133 sizeof(funcArgList) - 1, funcSrc, sizeof(funcSrc) - 1, JERRY_PARSE_NO_OPTS);
134
135 jerry_value_t funcArgs[1] = { value };
136
137 jerry_value_t valRet = jerry_call_function(funcVal, funcArgs[0], funcArgs, 1);
138
139 jerry_release_value(valRet);
140 jerry_release_value(funcVal);
141 }
142
jerry_strict_date(double time)143 jerry_value_t jerry_strict_date(double time)
144 {
145 const jerry_char_t funcResource[] = "unknown";
146 const jerry_char_t funcArgList[] = "v1 ";
147 const jerry_char_t funcSrc[] = " return new Date(v1) ";
148
149 jerry_value_t funcVal = jerry_parse_function(funcResource, sizeof(funcResource) - 1, funcArgList,
150 sizeof(funcArgList) - 1, funcSrc, sizeof(funcSrc) - 1, JERRY_PARSE_NO_OPTS);
151
152 jerry_value_t value = jerry_create_number(time);
153 jerry_value_t funcArgs[1] = { value };
154
155 jerry_value_t valRet = jerry_call_function(funcVal, funcArgs[0], funcArgs, 1);
156 jerry_release_value(funcVal);
157 return valRet;
158 }
159
jerry_get_date(jerry_value_t value)160 double jerry_get_date(jerry_value_t value)
161 {
162 const jerry_char_t funcResource[] = "unknown";
163 const jerry_char_t funcArgList[] = "v1 ";
164 const jerry_char_t funcSrc[] = " return v1.getTime() ";
165
166 jerry_value_t funcVal = jerry_parse_function(funcResource, sizeof(funcResource) - 1, funcArgList,
167 sizeof(funcArgList) - 1, funcSrc, sizeof(funcSrc) - 1, JERRY_PARSE_NO_OPTS);
168
169 jerry_value_t funcArgs[1] = { value };
170
171 jerry_value_t valRet = jerry_call_function(funcVal, funcArgs[0], funcArgs, 1);
172
173 double retTime = jerry_get_number_value(valRet);
174
175 jerry_release_value(valRet);
176 jerry_release_value(funcVal);
177
178 return retTime;
179 }
180
jerry_is_date(jerry_value_t value)181 bool jerry_is_date(jerry_value_t value)
182 {
183 jerry_value_t global = jerry_get_global_object();
184 jerry_value_t date = jerryx_get_property_str(global, "Date");
185 jerry_value_t result = jerry_binary_operation(JERRY_BIN_OP_INSTANCEOF, value, date);
186
187 bool retVal = jerry_get_boolean_value(result);
188
189 jerry_release_value(result);
190 jerry_release_value(date);
191 jerry_release_value(global);
192
193 return retVal;
194 }
195