• 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             }
96         } else {
97             free(nativePoint);
98         }
99     });
100 }
101 
~JerryScriptNativeBuffer()102 JerryScriptNativeBuffer::~JerryScriptNativeBuffer() {}
103 
GetInterface(int interfaceId)104 void* JerryScriptNativeBuffer::GetInterface(int interfaceId)
105 {
106     return (NativeBuffer::INTERFACE_ID == interfaceId) ? (NativeBuffer*)this
107         : JerryScriptNativeObject::GetInterface(interfaceId);
108 }
109 
GetBuffer()110 void* JerryScriptNativeBuffer::GetBuffer()
111 {
112     return jerry_get_arraybuffer_pointer(value_);
113 }
114 
GetLength()115 size_t JerryScriptNativeBuffer::GetLength()
116 {
117     return jerry_get_arraybuffer_byte_length(value_);
118 }
119 
CheckAndCreateBuffer(size_t length)120 jerry_value_t JerryScriptNativeBuffer::CheckAndCreateBuffer(size_t length)
121 {
122     jerry_value_t buf = NULL;
123 
124     if (length > kMaxByteLength) {
125         HILOG_ERROR("The length(%{public}zu) exceeds the maximum byte length definition(%{public}zu).",
126             length, kMaxByteLength);
127         buf = jerry_create_null();
128     } else {
129         buf = jerry_create_arraybuffer(length);
130     }
131     return buf;
132 }
133