• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_native_buffer.h"
17 
18 #include <map>
19 
20 #include "utils/log.h"
21 
22 // The maximum length for NativaBuffer, default is 2MiB.
23 static constexpr size_t kMaxByteLength = 2097152;
24 
25 static std::map<size_t, JerryScriptBufferCallback*> g_freeCallbackStorage;
26 
27 struct JerryScriptBufferCallback {
CreateNewInstanceJerryScriptBufferCallback28     static JerryScriptBufferCallback* CreateNewInstance()
29     {
30         return new JerryScriptBufferCallback();
31     }
32 
33     NativeEngine* engine = nullptr;
34     NativeFinalize cb = nullptr;
35     void* hint = nullptr;
36 };
37 
JerryScriptNativeBuffer(JerryScriptNativeEngine * engine,jerry_value_t value)38 JerryScriptNativeBuffer::JerryScriptNativeBuffer(JerryScriptNativeEngine* engine, jerry_value_t value)
39     : JerryScriptNativeObject(engine, value)
40 {
41 }
42 
JerryScriptNativeBuffer(JerryScriptNativeEngine * engine,uint8_t ** value,size_t length)43 JerryScriptNativeBuffer::JerryScriptNativeBuffer(JerryScriptNativeEngine* engine, uint8_t** value, size_t length)
44     : JerryScriptNativeBuffer(engine, CheckAndCreateBuffer(length))
45 {
46     if (length > kMaxByteLength) {
47         *value = nullptr;
48     } else {
49         *value = jerry_get_arraybuffer_pointer(value_);
50     }
51 }
52 
JerryScriptNativeBuffer(JerryScriptNativeEngine * engine,uint8_t ** value,size_t length,const uint8_t * data)53 JerryScriptNativeBuffer::JerryScriptNativeBuffer(JerryScriptNativeEngine* engine, uint8_t** value, size_t length,
54     const uint8_t* data) : JerryScriptNativeBuffer(engine, CheckAndCreateBuffer(length))
55 {
56     if (length > kMaxByteLength) {
57         *value = nullptr;
58         return;
59     }
60     if (data != nullptr) {
61         jerry_arraybuffer_write(value_, 0, data, length);
62     }
63     *value = jerry_get_arraybuffer_pointer(value_);
64 }
65 
JerryScriptNativeBuffer(JerryScriptNativeEngine * engine,uint8_t * data,size_t length,NativeFinalize callback,void * hint)66 JerryScriptNativeBuffer::JerryScriptNativeBuffer(JerryScriptNativeEngine* engine,
67                                                  uint8_t* data,
68                                                  size_t length,
69                                                  NativeFinalize callback,
70                                                  void* hint)
71     : JerryScriptNativeBuffer(engine, NULL)
72 {
73     if (length > kMaxByteLength) {
74         return;
75     }
76     auto freeCallback = JerryScriptBufferCallback::CreateNewInstance();
77     if (freeCallback != nullptr) {
78         freeCallback->engine = engine_;
79         freeCallback->cb = callback;
80         freeCallback->hint = hint;
81     }
82 
83     g_freeCallbackStorage.insert(std::pair<size_t, JerryScriptBufferCallback*>((size_t)data, freeCallback));
84     value_ = jerry_create_arraybuffer_external(length, data, [](void* nativePoint) {
85         auto iter = g_freeCallbackStorage.find((size_t)nativePoint);
86         if (iter != g_freeCallbackStorage.end()) {
87             auto callb = iter->second;
88             if (callb != nullptr && callb->cb != nullptr) {
89                 callb->cb(callb->engine, nativePoint, callb->hint);
90                 g_freeCallbackStorage.erase(iter);
91                 delete callb;
92                 callb = NULL;
93             } else {
94                 free(nativePoint);
95                 nativePoint = nullptr;
96             }
97         } else {
98             free(nativePoint);
99             nativePoint = nullptr;
100         }
101     });
102 }
103 
~JerryScriptNativeBuffer()104 JerryScriptNativeBuffer::~JerryScriptNativeBuffer() {}
105 
GetInterface(int interfaceId)106 void* JerryScriptNativeBuffer::GetInterface(int interfaceId)
107 {
108     return (NativeBuffer::INTERFACE_ID == interfaceId) ? (NativeBuffer*)this
109         : JerryScriptNativeObject::GetInterface(interfaceId);
110 }
111 
GetBuffer()112 void* JerryScriptNativeBuffer::GetBuffer()
113 {
114     return jerry_get_arraybuffer_pointer(value_);
115 }
116 
GetLength()117 size_t JerryScriptNativeBuffer::GetLength()
118 {
119     return jerry_get_arraybuffer_byte_length(value_);
120 }
121 
CheckAndCreateBuffer(size_t length)122 jerry_value_t JerryScriptNativeBuffer::CheckAndCreateBuffer(size_t length)
123 {
124     jerry_value_t buf = NULL;
125 
126     if (length > kMaxByteLength) {
127         HILOG_ERROR("The length(%{public}zu) exceeds the maximum byte length definition(%{public}zu).",
128             length, kMaxByteLength);
129         buf = jerry_create_null();
130     } else {
131         buf = jerry_create_arraybuffer(length);
132     }
133     return buf;
134 }
135