mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-27 09:37:31 +09:00
Issue #2692 - Part 2: Split out JS SourceBufferHolder to its own header.
This commit is contained in:
parent
9436bfa175
commit
565fb4b05a
3 changed files with 118 additions and 96 deletions
116
js/public/SourceBufferHolder.h
Normal file
116
js/public/SourceBufferHolder.h
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container class for passing in script source buffers to the JS engine. This
|
||||||
|
* not only groups the buffer and length values, it also provides a way to
|
||||||
|
* optionally pass ownership of the buffer to the JS engine without copying.
|
||||||
|
* Rules for use:
|
||||||
|
*
|
||||||
|
* 1) The data array must be allocated with js_malloc() or js_realloc() if
|
||||||
|
* ownership is being granted to the SourceBufferHolder.
|
||||||
|
* 2) If ownership is not given to the SourceBufferHolder, then the memory
|
||||||
|
* must be kept alive until the JS compilation is complete.
|
||||||
|
* 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
|
||||||
|
* memory alive until JS compilation completes. Normally only the JS
|
||||||
|
* engine should be calling take().
|
||||||
|
*
|
||||||
|
* Example use:
|
||||||
|
*
|
||||||
|
* size_t length = 512;
|
||||||
|
* char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
|
||||||
|
* JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
|
||||||
|
* JS::Compile(cx, options, srcBuf);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef js_SourceBufferHolder_h
|
||||||
|
#define js_SourceBufferHolder_h
|
||||||
|
|
||||||
|
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
||||||
|
|
||||||
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
|
#include "js/Utility.h" // JS::UniqueTwoByteChars
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
class MOZ_STACK_CLASS SourceBufferHolder final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Ownership {
|
||||||
|
NoOwnership,
|
||||||
|
GiveOwnership
|
||||||
|
};
|
||||||
|
|
||||||
|
SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
|
||||||
|
: data_(data),
|
||||||
|
length_(dataLength),
|
||||||
|
ownsChars_(ownership == GiveOwnership)
|
||||||
|
{
|
||||||
|
// Ensure that null buffers properly return an unowned, empty,
|
||||||
|
// null-terminated string.
|
||||||
|
static const char16_t NullChar_ = 0;
|
||||||
|
if (!get()) {
|
||||||
|
data_ = &NullChar_;
|
||||||
|
length_ = 0;
|
||||||
|
ownsChars_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceBufferHolder(SourceBufferHolder&& other)
|
||||||
|
: data_(other.data_),
|
||||||
|
length_(other.length_),
|
||||||
|
ownsChars_(other.ownsChars_)
|
||||||
|
{
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.length_ = 0;
|
||||||
|
other.ownsChars_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~SourceBufferHolder() {
|
||||||
|
if (ownsChars_)
|
||||||
|
js_free(const_cast<char16_t*>(data_));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access the underlying source buffer without affecting ownership.
|
||||||
|
const char16_t* get() const { return data_; }
|
||||||
|
|
||||||
|
// Length of the source buffer in char16_t code units (not bytes)
|
||||||
|
size_t length() const { return length_; }
|
||||||
|
|
||||||
|
// Returns true if the SourceBufferHolder owns the buffer and will free
|
||||||
|
// it upon destruction. If true, it is legal to call take().
|
||||||
|
bool ownsChars() const { return ownsChars_; }
|
||||||
|
|
||||||
|
// Retrieve and take ownership of the underlying data buffer. The caller
|
||||||
|
// is now responsible for calling js_free() on the returned value, *but only
|
||||||
|
// after JS script compilation has completed*.
|
||||||
|
//
|
||||||
|
// After the buffer has been taken the SourceBufferHolder functions as if
|
||||||
|
// it had been constructed on an unowned buffer; get() and length() still
|
||||||
|
// work. In order for this to be safe the taken buffer must be kept alive
|
||||||
|
// until after JS script compilation completes as noted above.
|
||||||
|
//
|
||||||
|
// Note, it's the caller's responsibility to check ownsChars() before taking
|
||||||
|
// the buffer. Taking and then free'ing an unowned buffer will have dire
|
||||||
|
// consequences.
|
||||||
|
char16_t* take() {
|
||||||
|
MOZ_ASSERT(ownsChars_);
|
||||||
|
ownsChars_ = false;
|
||||||
|
return const_cast<char16_t*>(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SourceBufferHolder(SourceBufferHolder&) = delete;
|
||||||
|
SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
|
||||||
|
|
||||||
|
const char16_t* data_;
|
||||||
|
size_t length_;
|
||||||
|
bool ownsChars_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace JS
|
||||||
|
|
||||||
|
#endif /* js_SourceBufferHolder_h */
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "js/Principals.h"
|
#include "js/Principals.h"
|
||||||
#include "js/Realm.h"
|
#include "js/Realm.h"
|
||||||
#include "js/RootingAPI.h"
|
#include "js/RootingAPI.h"
|
||||||
|
#include "js/SourceBufferHolder.h"
|
||||||
#include "js/Stream.h"
|
#include "js/Stream.h"
|
||||||
#include "js/TracingAPI.h"
|
#include "js/TracingAPI.h"
|
||||||
#include "js/UniquePtr.h"
|
#include "js/UniquePtr.h"
|
||||||
|
|
@ -751,102 +752,6 @@ JS_StringHasBeenPinned(JSContext* cx, JSString* str);
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
/**
|
|
||||||
* Container class for passing in script source buffers to the JS engine. This
|
|
||||||
* not only groups the buffer and length values, it also provides a way to
|
|
||||||
* optionally pass ownership of the buffer to the JS engine without copying.
|
|
||||||
* Rules for use:
|
|
||||||
*
|
|
||||||
* 1) The data array must be allocated with js_malloc() or js_realloc() if
|
|
||||||
* ownership is being granted to the SourceBufferHolder.
|
|
||||||
* 2) If ownership is not given to the SourceBufferHolder, then the memory
|
|
||||||
* must be kept alive until the JS compilation is complete.
|
|
||||||
* 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
|
|
||||||
* memory alive until JS compilation completes. Normally only the JS
|
|
||||||
* engine should be calling take().
|
|
||||||
*
|
|
||||||
* Example use:
|
|
||||||
*
|
|
||||||
* size_t length = 512;
|
|
||||||
* char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
|
|
||||||
* JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
|
|
||||||
* JS::Compile(cx, options, srcBuf);
|
|
||||||
*/
|
|
||||||
class MOZ_STACK_CLASS SourceBufferHolder final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Ownership {
|
|
||||||
NoOwnership,
|
|
||||||
GiveOwnership
|
|
||||||
};
|
|
||||||
|
|
||||||
SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
|
|
||||||
: data_(data),
|
|
||||||
length_(dataLength),
|
|
||||||
ownsChars_(ownership == GiveOwnership)
|
|
||||||
{
|
|
||||||
// Ensure that null buffers properly return an unowned, empty,
|
|
||||||
// null-terminated string.
|
|
||||||
static const char16_t NullChar_ = 0;
|
|
||||||
if (!get()) {
|
|
||||||
data_ = &NullChar_;
|
|
||||||
length_ = 0;
|
|
||||||
ownsChars_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceBufferHolder(SourceBufferHolder&& other)
|
|
||||||
: data_(other.data_),
|
|
||||||
length_(other.length_),
|
|
||||||
ownsChars_(other.ownsChars_)
|
|
||||||
{
|
|
||||||
other.data_ = nullptr;
|
|
||||||
other.length_ = 0;
|
|
||||||
other.ownsChars_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
~SourceBufferHolder() {
|
|
||||||
if (ownsChars_)
|
|
||||||
js_free(const_cast<char16_t*>(data_));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access the underlying source buffer without affecting ownership.
|
|
||||||
const char16_t* get() const { return data_; }
|
|
||||||
|
|
||||||
// Length of the source buffer in char16_t code units (not bytes)
|
|
||||||
size_t length() const { return length_; }
|
|
||||||
|
|
||||||
// Returns true if the SourceBufferHolder owns the buffer and will free
|
|
||||||
// it upon destruction. If true, it is legal to call take().
|
|
||||||
bool ownsChars() const { return ownsChars_; }
|
|
||||||
|
|
||||||
// Retrieve and take ownership of the underlying data buffer. The caller
|
|
||||||
// is now responsible for calling js_free() on the returned value, *but only
|
|
||||||
// after JS script compilation has completed*.
|
|
||||||
//
|
|
||||||
// After the buffer has been taken the SourceBufferHolder functions as if
|
|
||||||
// it had been constructed on an unowned buffer; get() and length() still
|
|
||||||
// work. In order for this to be safe the taken buffer must be kept alive
|
|
||||||
// until after JS script compilation completes as noted above.
|
|
||||||
//
|
|
||||||
// Note, it's the caller's responsibility to check ownsChars() before taking
|
|
||||||
// the buffer. Taking and then free'ing an unowned buffer will have dire
|
|
||||||
// consequences.
|
|
||||||
char16_t* take() {
|
|
||||||
MOZ_ASSERT(ownsChars_);
|
|
||||||
ownsChars_ = false;
|
|
||||||
return const_cast<char16_t*>(data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SourceBufferHolder(SourceBufferHolder&) = delete;
|
|
||||||
SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
|
|
||||||
|
|
||||||
const char16_t* data_;
|
|
||||||
size_t length_;
|
|
||||||
bool ownsChars_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace JS */
|
} /* namespace JS */
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ EXPORTS.js += [
|
||||||
'../public/Result.h',
|
'../public/Result.h',
|
||||||
'../public/RootingAPI.h',
|
'../public/RootingAPI.h',
|
||||||
'../public/SliceBudget.h',
|
'../public/SliceBudget.h',
|
||||||
|
'../public/SourceBufferHolder.h',
|
||||||
'../public/Stream.h',
|
'../public/Stream.h',
|
||||||
'../public/StructuredClone.h',
|
'../public/StructuredClone.h',
|
||||||
'../public/SweepingAPI.h',
|
'../public/SweepingAPI.h',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue