escargot/src/api/EscargotPublic.cpp
Youngil Choi 3148b0a2b1 Update license clauses
Signed-off-by: Youngil Choi <duddlf.choi@samsung.com>
2017-06-12 11:14:17 +09:00

1559 lines
44 KiB
C++

/*
* Copyright (c) 2017-present Samsung Electronics Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdlib> // size_t
#include "Escargot.h"
#include "GCUtil.h"
#include "util/Vector.h"
#include "EscargotPublic.h"
#include "parser/ScriptParser.h"
#include "parser/CodeBlock.h"
#include "runtime/Context.h"
#include "runtime/ExecutionContext.h"
#include "runtime/FunctionObject.h"
#include "runtime/Value.h"
#include "runtime/VMInstance.h"
#include "runtime/SandBox.h"
#include "runtime/Environment.h"
#include "runtime/ArrayObject.h"
#include "runtime/ErrorObject.h"
#ifdef ESCARGOT_ENABLE_PROMISE
#include "runtime/Job.h"
#include "runtime/JobQueue.h"
#include "runtime/PromiseObject.h"
#endif
#ifdef ESCARGOT_ENABLE_TYPEDARRAY
#include "runtime/ArrayBufferObject.h"
#include "runtime/TypedArrayObject.h"
#endif
namespace Escargot {
#define DEFINE_CAST(ClassName) \
inline ClassName* toImpl(ClassName##Ref* v) \
{ \
return reinterpret_cast<ClassName*>(v); \
} \
inline ClassName##Ref* toRef(ClassName* v) \
{ \
return reinterpret_cast<ClassName##Ref*>(v); \
}
DEFINE_CAST(VMInstance);
DEFINE_CAST(Context);
DEFINE_CAST(SandBox);
DEFINE_CAST(ExecutionState);
DEFINE_CAST(String);
DEFINE_CAST(PointerValue);
DEFINE_CAST(Object);
DEFINE_CAST(ArrayObject)
DEFINE_CAST(ErrorObject)
DEFINE_CAST(ReferenceErrorObject);
DEFINE_CAST(TypeErrorObject);
DEFINE_CAST(SyntaxErrorObject);
DEFINE_CAST(RangeErrorObject);
DEFINE_CAST(URIErrorObject);
DEFINE_CAST(EvalErrorObject);
DEFINE_CAST(GlobalObject);
DEFINE_CAST(FunctionObject);
#ifdef ESCARGOT_ENABLE_PROMISE
DEFINE_CAST(PromiseObject);
#endif
DEFINE_CAST(Script);
DEFINE_CAST(ScriptParser);
#if ESCARGOT_ENABLE_TYPEDARRAY
DEFINE_CAST(ArrayBufferObject);
DEFINE_CAST(ArrayBufferView);
#endif
#undef DEFINE_CAST
inline ValueRef* toRef(const Value& v)
{
return reinterpret_cast<ValueRef*>(SmallValue(v).payload());
}
inline Value toImpl(ValueRef* v)
{
return Value(SmallValue::fromPayload(v));
}
inline ValueVectorRef* toRef(const SmallValueVector* v)
{
return reinterpret_cast<ValueVectorRef*>(const_cast<SmallValueVector*>(v));
}
inline SmallValueVector* toImpl(ValueVectorRef* v)
{
return reinterpret_cast<SmallValueVector*>(v);
}
inline AtomicStringRef* toRef(const AtomicString& v)
{
return reinterpret_cast<AtomicStringRef*>(v.string());
}
inline AtomicString toImpl(AtomicStringRef* v)
{
return AtomicString::fromPayload(reinterpret_cast<void*>(v));
}
void Globals::initialize(bool applyMallOpt, bool applyGcOpt)
{
Heap::initialize(applyMallOpt, applyGcOpt);
}
void Globals::finalize()
{
}
StringRef* StringRef::fromASCII(const char* s)
{
return toRef(new ASCIIString(s, strlen(s)));
}
StringRef* StringRef::fromASCII(const char* s, size_t len)
{
return toRef(new ASCIIString(s, len));
}
StringRef* StringRef::fromUTF8(const char* s, size_t len)
{
return toRef(String::fromUTF8(s, len));
}
StringRef* StringRef::fromUTF16(const char16_t* s, size_t len)
{
return toRef(new UTF16String(s, len));
}
StringRef* StringRef::emptyString()
{
return toRef(String::emptyString);
}
char16_t StringRef::charAt(size_t idx)
{
return toImpl(this)->charAt(idx);
}
size_t StringRef::length()
{
return toImpl(this)->length();
}
bool StringRef::equals(StringRef* src)
{
return toImpl(this)->equals(toImpl(src));
}
std::string StringRef::toStdUTF8String()
{
auto ret = toImpl(this)->toUTF8StringData();
return std::string(ret.data(), ret.length());
}
bool PointerValueRef::isString()
{
return toImpl(this)->isString();
}
StringRef* PointerValueRef::asString()
{
return toRef(toImpl(this)->asString());
}
bool PointerValueRef::isObject()
{
return toImpl(this)->isString();
}
ObjectRef* PointerValueRef::asObject()
{
return toRef(toImpl(this)->asObject());
}
bool PointerValueRef::isFunctionObject()
{
return toImpl(this)->isFunctionObject();
}
ObjectRef* PointerValueRef::asFunctionObject()
{
return toRef(toImpl(this)->asFunctionObject());
}
bool PointerValueRef::isArrayObject()
{
return toImpl(this)->isArrayObject();
}
ArrayObjectRef* PointerValueRef::asArrayObject()
{
return toRef(toImpl(this)->asArrayObject());
}
bool PointerValueRef::isGlobalObject()
{
return toImpl(this)->isGlobalObject();
}
GlobalObjectRef* PointerValueRef::asGlobalObject()
{
return toRef(toImpl(this)->asGlobalObject());
}
bool PointerValueRef::isErrorObject()
{
return toImpl(this)->isErrorObject();
}
ErrorObjectRef* PointerValueRef::asErrorObject()
{
return toRef(toImpl(this)->asErrorObject());
}
#if ESCARGOT_ENABLE_TYPEDARRAY
bool PointerValueRef::isArrayBufferObject()
{
return toImpl(this)->isArrayBufferObject();
}
ArrayBufferObjectRef* PointerValueRef::asArrayBufferObject()
{
return toRef(toImpl(this)->asArrayBufferObject());
}
bool PointerValueRef::isArrayBufferView()
{
return toImpl(this)->isArrayBufferObject();
}
ArrayBufferViewRef* PointerValueRef::asArrayBufferView()
{
return toRef(toImpl(this)->asArrayBufferView());
}
#endif
#if ESCARGOT_ENABLE_PROMISE
bool PointerValueRef::isPromiseObject()
{
return toImpl(this)->isPromiseObject();
}
PromiseObjectRef* PointerValueRef::asPromiseObject()
{
return toRef(toImpl(this)->asPromiseObject());
}
#endif
VMInstanceRef* VMInstanceRef::create(const char* locale, const char* timezone)
{
return toRef(new (NoGC) VMInstance(locale, timezone));
}
void VMInstanceRef::destroy()
{
VMInstance* imp = toImpl(this);
delete imp;
}
bool VMInstanceRef::addRoot(VMInstanceRef* instanceRef, ValueRef* ptr)
{
auto value = SmallValue::fromPayload(ptr);
if (!value.isStoredInHeap()) {
return false;
}
void* vptr = reinterpret_cast<void*>(value.payload());
toImpl(this)->addRoot(vptr);
return true;
}
bool VMInstanceRef::removeRoot(VMInstanceRef* instanceRef, ValueRef* ptr)
{
auto value = SmallValue::fromPayload(ptr);
if (!value.isStoredInHeap()) {
return false;
}
void* vptr = reinterpret_cast<void*>(value.payload());
return toImpl(this)->removeRoot(vptr);
}
#ifdef ESCARGOT_ENABLE_PROMISE
ValueRef* VMInstanceRef::drainJobQueue(ExecutionStateRef* state)
{
VMInstance* imp = toImpl(this);
return toRef(imp->drainJobQueue(*toImpl(state)));
}
void VMInstanceRef::setNewPromiseJobListener(NewPromiseJobListener l)
{
VMInstance* imp = toImpl(this);
imp->m_publicJobQueueListenerPointer = (void*)l;
imp->setNewPromiseJobListener([](ExecutionState& state) {
((NewPromiseJobListener)state.context()->vmInstance()->m_publicJobQueueListenerPointer)(toRef(&state));
});
}
#endif
ContextRef* ContextRef::create(VMInstanceRef* vminstanceref)
{
VMInstance* vminstance = toImpl(vminstanceref);
return toRef(new Context(vminstance));
}
void ContextRef::destroy()
{
Context* imp = toImpl(this);
delete imp;
}
ContextRef* ExecutionStateRef::context()
{
return toRef(toImpl(this)->context());
}
AtomicStringRef* AtomicStringRef::create(ContextRef* c, const char* src)
{
AtomicString a(toImpl(c), src, strlen(src));
return toRef(a);
}
AtomicStringRef* AtomicStringRef::create(ContextRef* c, StringRef* src)
{
AtomicString a(toImpl(c), toImpl(src));
return toRef(a);
}
AtomicStringRef* AtomicStringRef::emptyAtomicString()
{
AtomicString a;
return toRef(a);
}
StringRef* AtomicStringRef::string()
{
return toRef(toImpl(this).string());
}
ScriptParserRef* ContextRef::scriptParser()
{
Context* imp = toImpl(this);
return toRef(&imp->scriptParser());
}
ValueVectorRef* ValueVectorRef::create(size_t size)
{
return toRef(new (GC) SmallValueVector(size));
}
size_t ValueVectorRef::size()
{
return toImpl(this)->size();
}
void ValueVectorRef::pushBack(ValueRef* val)
{
toImpl(this)->pushBack(SmallValue::fromPayload(val));
}
void ValueVectorRef::insert(size_t pos, ValueRef* val)
{
toImpl(this)->insert(pos, SmallValue::fromPayload(val));
}
void ValueVectorRef::erase(size_t pos)
{
toImpl(this)->erase(pos);
}
void ValueVectorRef::erase(size_t start, size_t end)
{
toImpl(this)->erase(start, end);
}
ValueRef* ValueVectorRef::at(const size_t& idx)
{
return reinterpret_cast<ValueRef*>((*toImpl(this))[idx].payload());
}
void ValueVectorRef::set(const size_t& idx, ValueRef* newValue)
{
toImpl(this)->data()[idx] = SmallValue::fromPayload(newValue);
}
void ValueVectorRef::resize(size_t newSize)
{
toImpl(this)->resize(newSize);
}
ObjectRef* ObjectRef::create(ExecutionStateRef* state)
{
return toRef(new Object(*toImpl(state)));
}
// can not redefine or delete virtual property
class ExposableObject : public Object {
public:
ExposableObject(ExecutionState& state, ExposableObjectGetOwnPropertyCallback getOwnPropetyCallback, ExposableObjectDefineOwnPropertyCallback defineOwnPropertyCallback, ExposableObjectEnumerationCallback enumerationCallback)
: Object(state)
, m_getOwnPropetyCallback(getOwnPropetyCallback)
, m_defineOwnPropertyCallback(defineOwnPropertyCallback)
, m_enumerationCallback(enumerationCallback)
{
}
virtual ObjectGetResult getOwnProperty(ExecutionState& state, const ObjectPropertyName& P) ESCARGOT_OBJECT_SUBCLASS_MUST_REDEFINE
{
auto result = m_getOwnPropetyCallback(toRef(&state), toRef(this), toRef(P.toValue(state)));
if (!result.m_value->isEmpty()) {
return ObjectGetResult(toImpl(result.m_value), result.m_isWritable, result.m_isEnumerable, result.m_isConfigurable);
}
return Object::getOwnProperty(state, P);
}
virtual bool defineOwnProperty(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc) ESCARGOT_OBJECT_SUBCLASS_MUST_REDEFINE
{
auto result = m_getOwnPropetyCallback(toRef(&state), toRef(this), toRef(P.toValue(state)));
if (!result.m_value->isEmpty()) {
if (desc.isValuePresent()) {
m_defineOwnPropertyCallback(toRef(&state), toRef(this), toRef(P.toValue(state)), toRef(desc.value()));
}
return false;
}
return Object::defineOwnProperty(state, P, desc);
}
virtual bool deleteOwnProperty(ExecutionState& state, const ObjectPropertyName& P) ESCARGOT_OBJECT_SUBCLASS_MUST_REDEFINE
{
auto result = m_getOwnPropetyCallback(toRef(&state), toRef(this), toRef(P.toValue(state)));
if (!result.m_value->isEmpty()) {
return false;
}
return Object::deleteOwnProperty(state, P);
}
virtual void enumeration(ExecutionState& state, bool (*callback)(ExecutionState& state, Object* self, const ObjectPropertyName&, const ObjectStructurePropertyDescriptor& desc, void* data), void* data) ESCARGOT_OBJECT_SUBCLASS_MUST_REDEFINE
{
auto names = m_enumerationCallback(toRef(&state), toRef(this));
for (size_t i = 0; i < names.size(); i++) {
int attr = 0;
if (names[i].m_isWritable) {
attr = attr | ObjectStructurePropertyDescriptor::PresentAttribute::WritablePresent;
}
if (names[i].m_isEnumerable) {
attr = attr | ObjectStructurePropertyDescriptor::PresentAttribute::EnumerablePresent;
}
if (names[i].m_isConfigurable) {
attr = attr | ObjectStructurePropertyDescriptor::PresentAttribute::ConfigurablePresent;
}
ObjectStructurePropertyDescriptor desc = ObjectStructurePropertyDescriptor::createDataDescriptor((ObjectStructurePropertyDescriptor::PresentAttribute)attr);
callback(state, this, ObjectPropertyName(state, toImpl(names[i].m_name)), desc, data);
}
Object::enumeration(state, callback, data);
}
virtual bool isInlineCacheable()
{
return false;
}
protected:
ExposableObjectGetOwnPropertyCallback m_getOwnPropetyCallback;
ExposableObjectDefineOwnPropertyCallback m_defineOwnPropertyCallback;
ExposableObjectEnumerationCallback m_enumerationCallback;
};
ObjectRef* ObjectRef::createExposableObject(ExecutionStateRef* state,
ExposableObjectGetOwnPropertyCallback getOwnPropertyCallback, ExposableObjectDefineOwnPropertyCallback defineOwnPropertyCallback,
ExposableObjectEnumerationCallback enumerationCallback)
{
return toRef(new ExposableObject(*toImpl(state), getOwnPropertyCallback, defineOwnPropertyCallback, enumerationCallback));
}
ValueRef* ObjectRef::get(ExecutionStateRef* state, ValueRef* propertyName)
{
auto result = toImpl(this)->get(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)));
if (result.hasValue()) {
return toRef(result.value(*toImpl(state), toImpl(this)));
}
return ValueRef::createUndefined();
}
ValueRef* ObjectRef::getOwnProperty(ExecutionStateRef* state, ValueRef* propertyName)
{
auto result = toImpl(this)->getOwnProperty(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)));
if (result.hasValue()) {
return toRef(result.value(*toImpl(state), toImpl(this)));
}
return ValueRef::createUndefined();
}
void* ObjectRef::NativeDataAccessorPropertyData::operator new(size_t size)
{
return GC_MALLOC_ATOMIC(size);
}
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::NotPresent == (int)ObjectPropertyDescriptor::NotPresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::WritablePresent == (int)ObjectPropertyDescriptor::WritablePresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::EnumerablePresent == (int)ObjectPropertyDescriptor::EnumerablePresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::ConfigurablePresent == (int)ObjectPropertyDescriptor::ConfigurablePresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::NonWritablePresent == (int)ObjectPropertyDescriptor::NonWritablePresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::NonEnumerablePresent == (int)ObjectPropertyDescriptor::NonEnumerablePresent, "");
COMPILE_ASSERT((int)ObjectRef::PresentAttribute::NonConfigurablePresent == (int)ObjectPropertyDescriptor::NonConfigurablePresent, "");
bool ObjectRef::defineDataProperty(ExecutionStateRef* state, ValueRef* propertyName, const DataPropertyDescriptor& desc)
{
return toImpl(this)->defineOwnProperty(*toImpl(state),
ObjectPropertyName(*toImpl(state), toImpl(propertyName)), ObjectPropertyDescriptor(toImpl(desc.m_value), (ObjectPropertyDescriptor::PresentAttribute)desc.m_attribute));
}
bool ObjectRef::defineDataProperty(ExecutionStateRef* state, ValueRef* propertyName, ValueRef* value, bool isWritable, bool isEnumerable, bool isConfigurable)
{
int attr = 0;
if (isWritable)
attr = attr | ObjectPropertyDescriptor::WritablePresent;
else
attr = attr | ObjectPropertyDescriptor::NonWritablePresent;
if (isEnumerable)
attr = attr | ObjectPropertyDescriptor::EnumerablePresent;
else
attr = attr | ObjectPropertyDescriptor::NonEnumerablePresent;
if (isConfigurable)
attr = attr | ObjectPropertyDescriptor::ConfigurablePresent;
else
attr = attr | ObjectPropertyDescriptor::NonConfigurablePresent;
return toImpl(this)->defineOwnProperty(*toImpl(state),
ObjectPropertyName(*toImpl(state), toImpl(propertyName)), ObjectPropertyDescriptor(toImpl(value), (ObjectPropertyDescriptor::PresentAttribute)attr));
}
bool ObjectRef::defineAccessorProperty(ExecutionStateRef* state, ValueRef* propertyName, const AccessorPropertyDescriptor& desc)
{
return toImpl(this)->defineOwnProperty(*toImpl(state),
ObjectPropertyName(*toImpl(state), toImpl(propertyName)), ObjectPropertyDescriptor(JSGetterSetter(toImpl(desc.m_getter), toImpl(desc.m_setter)), (ObjectPropertyDescriptor::PresentAttribute)desc.m_attribute));
}
bool ObjectRef::defineNativeDataAccessorProperty(ExecutionStateRef* state, ValueRef* propertyName, NativeDataAccessorPropertyData* publicData)
{
ObjectPropertyNativeGetterSetterData* innerData = new ObjectPropertyNativeGetterSetterData(publicData->m_isWritable, publicData->m_isEnumerable, publicData->m_isConfigurable, [](ExecutionState& state, Object* self, const SmallValue& privateDataFromObjectPrivateArea) -> Value {
NativeDataAccessorPropertyData* publicData = reinterpret_cast<NativeDataAccessorPropertyData*>(privateDataFromObjectPrivateArea.payload());
return toImpl(publicData->m_getter(toRef(&state), toRef(self), publicData));
},
nullptr);
if (!publicData->m_isWritable) {
innerData->m_setter = nullptr;
} else if (publicData->m_isWritable && !publicData->m_setter) {
innerData->m_setter = [](ExecutionState& state, Object* self, SmallValue& privateDataFromObjectPrivateArea, const Value& setterInputData) -> bool {
return false;
};
} else {
innerData->m_setter = [](ExecutionState& state, Object* self, SmallValue& privateDataFromObjectPrivateArea, const Value& setterInputData) -> bool {
NativeDataAccessorPropertyData* publicData = reinterpret_cast<NativeDataAccessorPropertyData*>(privateDataFromObjectPrivateArea.payload());
// ExecutionStateRef* state, ObjectRef* self, NativeDataAccessorPropertyData* data, ValueRef* setterInputData
return publicData->m_setter(toRef(&state), toRef(self), publicData, toRef(setterInputData));
};
}
return toImpl(this)->defineNativeDataAccessorProperty(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)), innerData, Value(Value::FromPayload, (intptr_t)publicData));
}
bool ObjectRef::set(ExecutionStateRef* state, ValueRef* propertyName, ValueRef* value)
{
return toImpl(this)->set(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)), toImpl(value), toImpl(this));
}
bool ObjectRef::deleteOwnProperty(ExecutionStateRef* state, ValueRef* propertyName)
{
return toImpl(this)->deleteOwnProperty(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)));
}
bool ObjectRef::hasOwnProperty(ExecutionStateRef* state, ValueRef* propertyName)
{
return toImpl(this)->hasOwnProperty(*toImpl(state), ObjectPropertyName(*toImpl(state), toImpl(propertyName)));
}
ValueRef* ObjectRef::getPrototype(ExecutionStateRef* state)
{
return toRef(toImpl(this)->getPrototype(*toImpl(state)));
}
ObjectRef* ObjectRef::getPrototypeObject()
{
return toRef(toImpl(this)->getPrototypeObject());
}
void ObjectRef::setPrototype(ExecutionStateRef* state, ValueRef* value)
{
toImpl(this)->setPrototype(*toImpl(state), toImpl(value));
}
bool ObjectRef::isExtensible()
{
return toImpl(this)->isExtensible();
}
void ObjectRef::preventExtensions()
{
toImpl(this)->preventExtensions();
}
// http://www.ecma-international.org/ecma-262/5.1/#sec-8.6.2
const char* ObjectRef::internalClassProperty()
{
return toImpl(this)->internalClassProperty();
}
void ObjectRef::giveInternalClassProperty(const char* name)
{
toImpl(this)->giveInternalClassProperty(name);
}
void* ObjectRef::extraData()
{
return toImpl(this)->extraData();
}
void ObjectRef::setExtraData(void* e)
{
toImpl(this)->setExtraData(e);
}
void ObjectRef::removeFromHiddenClassChain(ExecutionStateRef* state)
{
toImpl(this)->markThisObjectDontNeedStructureTransitionTable(*toImpl(state));
}
FunctionObjectRef* GlobalObjectRef::object()
{
return toRef(toImpl(this)->object());
}
ObjectRef* GlobalObjectRef::objectPrototype()
{
return toRef(toImpl(this)->objectPrototype());
}
FunctionObjectRef* GlobalObjectRef::objectPrototypeToString()
{
return toRef(toImpl(this)->objectPrototypeToString());
}
FunctionObjectRef* GlobalObjectRef::function()
{
return toRef(toImpl(this)->function());
}
FunctionObjectRef* GlobalObjectRef::functionPrototype()
{
return toRef(toImpl(this)->functionPrototype());
}
FunctionObjectRef* GlobalObjectRef::error()
{
return toRef(toImpl(this)->error());
}
ObjectRef* GlobalObjectRef::errorPrototype()
{
return toRef(toImpl(this)->errorPrototype());
}
FunctionObjectRef* GlobalObjectRef::referenceError()
{
return toRef(toImpl(this)->referenceError());
}
ObjectRef* GlobalObjectRef::referenceErrorPrototype()
{
return toRef(toImpl(this)->referenceErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::typeError()
{
return toRef(toImpl(this)->typeError());
}
ObjectRef* GlobalObjectRef::typeErrorPrototype()
{
return toRef(toImpl(this)->typeErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::rangeError()
{
return toRef(toImpl(this)->rangeError());
}
ObjectRef* GlobalObjectRef::rangeErrorPrototype()
{
return toRef(toImpl(this)->rangeErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::syntaxError()
{
return toRef(toImpl(this)->syntaxError());
}
ObjectRef* GlobalObjectRef::syntaxErrorPrototype()
{
return toRef(toImpl(this)->syntaxErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::uriError()
{
return toRef(toImpl(this)->uriError());
}
ObjectRef* GlobalObjectRef::uriErrorPrototype()
{
return toRef(toImpl(this)->uriErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::evalError()
{
return toRef(toImpl(this)->evalError());
}
ObjectRef* GlobalObjectRef::evalErrorPrototype()
{
return toRef(toImpl(this)->evalErrorPrototype());
}
FunctionObjectRef* GlobalObjectRef::string()
{
return toRef(toImpl(this)->string());
}
ObjectRef* GlobalObjectRef::stringPrototype()
{
return toRef(toImpl(this)->stringPrototype());
}
FunctionObjectRef* GlobalObjectRef::number()
{
return toRef(toImpl(this)->number());
}
ObjectRef* GlobalObjectRef::numberPrototype()
{
return toRef(toImpl(this)->numberPrototype());
}
FunctionObjectRef* GlobalObjectRef::array()
{
return toRef(toImpl(this)->array());
}
ObjectRef* GlobalObjectRef::arrayPrototype()
{
return toRef(toImpl(this)->arrayPrototype());
}
FunctionObjectRef* GlobalObjectRef::boolean()
{
return toRef(toImpl(this)->boolean());
}
ObjectRef* GlobalObjectRef::booleanPrototype()
{
return toRef(toImpl(this)->booleanPrototype());
}
FunctionObjectRef* GlobalObjectRef::date()
{
return toRef(toImpl(this)->date());
}
ObjectRef* GlobalObjectRef::datePrototype()
{
return toRef(toImpl(this)->datePrototype());
}
ObjectRef* GlobalObjectRef::math()
{
return toRef(toImpl(this)->math());
}
FunctionObjectRef* GlobalObjectRef::regexp()
{
return toRef(toImpl(this)->regexp());
}
ObjectRef* GlobalObjectRef::regexpPrototype()
{
return toRef(toImpl(this)->regexpPrototype());
}
ObjectRef* GlobalObjectRef::json()
{
return toRef(toImpl(this)->json());
}
FunctionObjectRef* GlobalObjectRef::jsonStringify()
{
return toRef(toImpl(this)->jsonStringify());
}
FunctionObjectRef* GlobalObjectRef::jsonParse()
{
return toRef(toImpl(this)->jsonParse());
}
#if ESCARGOT_ENABLE_PROMISE
FunctionObjectRef* GlobalObjectRef::promise()
{
return toRef(toImpl(this)->promise());
}
ObjectRef* GlobalObjectRef::promisePrototype()
{
return toRef(toImpl(this)->promisePrototype());
}
#endif
#if ESCARGOT_ENABLE_TYPEDARRAY
FunctionObjectRef* GlobalObjectRef::arrayBuffer()
{
return toRef(toImpl(this)->arrayBuffer());
}
ObjectRef* GlobalObjectRef::arrayBufferPrototype()
{
return toRef(toImpl(this)->arrayBufferPrototype());
}
FunctionObjectRef* GlobalObjectRef::dataView()
{
return toRef(toImpl(this)->dataView());
}
ObjectRef* GlobalObjectRef::dataViewPrototype()
{
return toRef(toImpl(this)->dataViewPrototype());
}
ObjectRef* GlobalObjectRef::int8Array()
{
return toRef(toImpl(this)->int8Array());
}
ObjectRef* GlobalObjectRef::int8ArrayPrototype()
{
return toRef(toImpl(this)->int8ArrayPrototype());
}
ObjectRef* GlobalObjectRef::uint8Array()
{
return toRef(toImpl(this)->uint8Array());
}
ObjectRef* GlobalObjectRef::uint8ArrayPrototype()
{
return toRef(toImpl(this)->uint8ArrayPrototype());
}
ObjectRef* GlobalObjectRef::int16Array()
{
return toRef(toImpl(this)->int16Array());
}
ObjectRef* GlobalObjectRef::int16ArrayPrototype()
{
return toRef(toImpl(this)->int16ArrayPrototype());
}
ObjectRef* GlobalObjectRef::uint16Array()
{
return toRef(toImpl(this)->uint16Array());
}
ObjectRef* GlobalObjectRef::uint16ArrayPrototype()
{
return toRef(toImpl(this)->uint16ArrayPrototype());
}
ObjectRef* GlobalObjectRef::int32Array()
{
return toRef(toImpl(this)->int32Array());
}
ObjectRef* GlobalObjectRef::int32ArrayPrototype()
{
return toRef(toImpl(this)->int32ArrayPrototype());
}
ObjectRef* GlobalObjectRef::uint32Array()
{
return toRef(toImpl(this)->uint32Array());
}
ObjectRef* GlobalObjectRef::uint32ArrayPrototype()
{
return toRef(toImpl(this)->uint32ArrayPrototype());
}
ObjectRef* GlobalObjectRef::uint8ClampedArray()
{
return toRef(toImpl(this)->uint8ClampedArray());
}
ObjectRef* GlobalObjectRef::uint8ClampedArrayPrototype()
{
return toRef(toImpl(this)->uint8ClampedArrayPrototype());
}
ObjectRef* GlobalObjectRef::float32Array()
{
return toRef(toImpl(this)->float32Array());
}
ObjectRef* GlobalObjectRef::float32ArrayPrototype()
{
return toRef(toImpl(this)->float32ArrayPrototype());
}
ObjectRef* GlobalObjectRef::float64Array()
{
return toRef(toImpl(this)->float64Array());
}
ObjectRef* GlobalObjectRef::float64ArrayPrototype()
{
return toRef(toImpl(this)->float64ArrayPrototype());
}
#endif
class CallPublicFunctionData : public CallNativeFunctionData {
public:
FunctionObjectRef::NativeFunctionPointer m_publicFn;
FunctionObjectRef::NativeFunctionConstructor m_publicCtor;
};
static Value publicFunctionBridge(ExecutionState& state, Value thisValue, size_t calledArgc, Value* calledArgv, bool isNewExpression)
{
CodeBlock* dataCb = state.executionContext()->lexicalEnvironment()->record()->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord()->functionObject()->codeBlock();
CallPublicFunctionData* code = (CallPublicFunctionData*)(dataCb->nativeFunctionData());
ValueRef** newArgv = ALLOCA(sizeof(ValueRef*) * calledArgc, ValueRef*, state);
for (size_t i = 0; i < calledArgc; i++) {
newArgv[i] = toRef(calledArgv[i]);
}
return toImpl(code->m_publicFn(toRef(&state), toRef(thisValue), calledArgc, newArgv, isNewExpression));
}
static FunctionObjectRef* createFunction(ExecutionStateRef* state, FunctionObjectRef::NativeFunctionInfo info, bool isBuiltin)
{
CallPublicFunctionData* data = new CallPublicFunctionData();
data->m_fn = publicFunctionBridge;
data->m_publicFn = info.m_nativeFunction;
if (info.m_isConstructor && info.m_nativeFunctionConstructor) {
data->m_publicCtor = info.m_nativeFunctionConstructor;
data->m_ctorFn = [](ExecutionState& state, CodeBlock* codeBlock, size_t argc, Value* argv) -> Object* {
ValueRef** newArgv = ALLOCA(sizeof(ValueRef*) * argc, ValueRef*, state);
for (size_t i = 0; i < argc; i++) {
newArgv[i] = toRef(argv[i]);
}
return toImpl(((CallPublicFunctionData*)codeBlock->nativeFunctionData())->m_publicCtor(toRef(&state), argc, newArgv));
};
} else if (info.m_isConstructor) {
data->m_publicCtor = nullptr;
data->m_ctorFn = [](ExecutionState& state, CodeBlock* cb, size_t argc, Value* argv) -> Object* {
return new Object(state);
};
} else {
data->m_publicCtor = nullptr;
data->m_ctorFn = nullptr;
}
CodeBlock* cb = new CodeBlock(toImpl(state)->context(), toImpl(info.m_name), info.m_argumentCount, info.m_isStrict, info.m_isConstructor, data);
FunctionObject* f;
if (isBuiltin)
f = new FunctionObject(*toImpl(state), cb, FunctionObject::__ForBuiltin__);
else
f = new FunctionObject(*toImpl(state), cb, nullptr);
return toRef(f);
}
FunctionObjectRef* FunctionObjectRef::create(ExecutionStateRef* state, FunctionObjectRef::NativeFunctionInfo info)
{
return createFunction(state, info, false);
}
FunctionObjectRef* FunctionObjectRef::createBuiltinFunction(ExecutionStateRef* state, FunctionObjectRef::NativeFunctionInfo info)
{
return createFunction(state, info, true);
}
ValueRef* FunctionObjectRef::getFunctionPrototype(ExecutionStateRef* state)
{
FunctionObject* o = toImpl(this);
return toRef(o->getFunctionPrototype(*toImpl(state)));
}
bool FunctionObjectRef::setFunctionPrototype(ExecutionStateRef* state, ValueRef* v)
{
FunctionObject* o = toImpl(this);
return o->setFunctionPrototype(*toImpl(state), toImpl(v));
}
bool FunctionObjectRef::isConstructor()
{
FunctionObject* o = toImpl(this);
return o->isConstructor();
}
ValueRef* FunctionObjectRef::call(ExecutionStateRef* state, ValueRef* receiver, const size_t& argc, ValueRef** argv)
{
FunctionObject* o = toImpl(this);
Value* newArgv = ALLOCA(sizeof(Value) * argc, Value, state);
for (size_t i = 0; i < argc; i++) {
newArgv[i] = toImpl(argv[i]);
}
return toRef(o->call(*toImpl(state), toImpl(receiver), argc, newArgv));
}
ObjectRef* FunctionObjectRef::newInstance(ExecutionStateRef* state, const size_t& argc, ValueRef** argv)
{
FunctionObject* o = toImpl(this);
Value* newArgv = ALLOCA(sizeof(Value) * argc, Value, state);
for (size_t i = 0; i < argc; i++) {
newArgv[i] = toImpl(argv[i]);
}
return toRef(o->newInstance(*toImpl(state), argc, newArgv));
}
static void markEvalToCodeblock(InterpretedCodeBlock* cb)
{
cb->setHasEval();
cb->computeVariables();
for (size_t i = 0; i < cb->childBlocks().size(); i++) {
markEvalToCodeblock(cb->childBlocks()[i]->asInterpretedCodeBlock());
}
}
void FunctionObjectRef::markFunctionNeedsSlowVirtualIdentifierOperation()
{
FunctionObject* o = toImpl(this);
if (o->codeBlock()->isInterpretedCodeBlock()) {
markEvalToCodeblock(o->codeBlock()->asInterpretedCodeBlock());
o->codeBlock()->setNeedsVirtualIDOperation();
}
}
SandBoxRef* SandBoxRef::create(ContextRef* contextRef)
{
Context* ctx = toImpl(contextRef);
return toRef(new SandBox(ctx));
}
void SandBoxRef::destroy()
{
SandBox* imp = toImpl(this);
delete imp;
}
SandBoxRef::StackTraceData::StackTraceData()
: fileName(toRef(String::emptyString))
, loc(SIZE_MAX, SIZE_MAX, SIZE_MAX)
{
}
SandBoxRef::SandBoxResult::SandBoxResult()
: result(ValueRef::createEmpty())
, error(ValueRef::createEmpty())
, msgStr(toRef(String::emptyString))
{
}
SandBoxRef::SandBoxResult SandBoxRef::run(const std::function<ValueRef*(ExecutionStateRef* state)>& scriptRunner)
{
auto result = toImpl(this)->run([&]() -> Value {
ExecutionState state(toImpl(this)->context());
return toImpl(scriptRunner(toRef(&state)));
});
SandBoxRef::SandBoxResult r;
r.error = toRef(result.error);
r.msgStr = toRef(result.msgStr);
r.result = toRef(result.result);
if (!result.error.isEmpty()) {
for (size_t i = 0; i < result.stackTraceData.size(); i++) {
SandBoxRef::StackTraceData t;
t.fileName = toRef(result.stackTraceData[i].fileName);
t.loc.line = result.stackTraceData[i].loc.line;
t.loc.column = result.stackTraceData[i].loc.column;
r.stackTraceData.push_back(t);
}
}
return r;
}
GlobalObjectRef* ContextRef::globalObject()
{
Context* ctx = toImpl(this);
return toRef(ctx->globalObject());
}
VMInstanceRef* ContextRef::vmInstance()
{
Context* ctx = toImpl(this);
return toRef(ctx->vmInstance());
}
void ContextRef::setVirtualIdentifierCallback(VirtualIdentifierCallback cb)
{
Context* ctx = toImpl(this);
ctx->m_virtualIdentifierCallbackPublic = (void*)cb;
ctx->setVirtualIdentifierCallback([](ExecutionState& state, Value name) -> Value {
if (state.context()->m_virtualIdentifierCallbackPublic) {
return toImpl(((VirtualIdentifierCallback)state.context()->m_virtualIdentifierCallbackPublic)(toRef(&state), toRef(name)));
}
return Value(Value::EmptyValue);
});
}
ContextRef::VirtualIdentifierCallback ContextRef::virtualIdentifierCallback()
{
Context* ctx = toImpl(this);
return ((VirtualIdentifierCallback)ctx->m_virtualIdentifierCallbackPublic);
}
ExecutionStateRef* ExecutionStateRef::create(ContextRef* ctxref)
{
Context* ctx = toImpl(ctxref);
return toRef(new ExecutionState(ctx));
}
void ExecutionStateRef::destroy()
{
ExecutionState* imp = toImpl(this);
delete imp;
}
FunctionObjectRef* ExecutionStateRef::resolveCallee()
{
return toRef(toImpl(this)->executionContext()->resolveCallee());
}
std::vector<std::pair<FunctionObjectRef*, ValueRef*>> ExecutionStateRef::resolveCallstack()
{
ExecutionState* state = toImpl(this);
std::vector<std::pair<FunctionObjectRef*, ValueRef*>> result;
while (state) {
if (state->executionContext() && state->executionContext()->lexicalEnvironment()->record()->isDeclarativeEnvironmentRecord()
&& state->executionContext()->lexicalEnvironment()->record()->asDeclarativeEnvironmentRecord()->isFunctionEnvironmentRecord()) {
auto r = state->executionContext()->lexicalEnvironment()->record()->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord();
FunctionObject* callee = r->functionObject();
Value thisValue = state->registerFile()[0];
result.push_back(std::make_pair(toRef(callee), toRef(thisValue)));
}
state = state->parent();
}
return result;
}
void ExecutionStateRef::throwException(ValueRef* value)
{
ExecutionState* imp = toImpl(this);
imp->throwException(toImpl(value));
}
ValueRef* ValueRef::create(bool value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(int value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(unsigned value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(float value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(double value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(long value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(unsigned long value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(long long value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::create(unsigned long long value)
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(value)).payload());
}
ValueRef* ValueRef::createNull()
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(Value::Null))
.payload());
}
ValueRef* ValueRef::createEmpty()
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(Value::EmptyValue))
.payload());
}
ValueRef* ValueRef::createUndefined()
{
return reinterpret_cast<ValueRef*>(SmallValue(Value(Value::Undefined))
.payload());
}
bool ValueRef::isBoolean() const
{
return Value(SmallValue::fromPayload(this)).isBoolean();
}
bool ValueRef::isStoreInHeap() const
{
auto value = SmallValue::fromPayload(this);
if (value.isStoredInHeap()) {
return true;
}
return false;
}
bool ValueRef::isNumber() const
{
return Value(SmallValue::fromPayload(this)).isNumber();
}
bool ValueRef::isNull() const
{
return Value(SmallValue::fromPayload(this)).isNull();
}
bool ValueRef::isUndefined() const
{
return Value(SmallValue::fromPayload(this)).isUndefined();
}
bool ValueRef::isString() const
{
return Value(SmallValue::fromPayload(this)).isString();
}
bool ValueRef::isObject() const
{
return Value(SmallValue::fromPayload(this)).isObject();
}
bool ValueRef::isInt32() const
{
return Value(SmallValue::fromPayload(this)).isInt32();
}
bool ValueRef::isUInt32() const
{
return Value(SmallValue::fromPayload(this)).isUInt32();
}
bool ValueRef::isDouble() const
{
return Value(SmallValue::fromPayload(this)).isDouble();
}
bool ValueRef::isTrue() const
{
return Value(SmallValue::fromPayload(this)).isTrue();
}
bool ValueRef::isFalse() const
{
return Value(SmallValue::fromPayload(this)).isFalse();
}
bool ValueRef::isEmpty() const
{
return Value(SmallValue::fromPayload(this)).isEmpty();
}
bool ValueRef::isFunction() const
{
return Value(SmallValue::fromPayload(this)).isFunction();
}
bool ValueRef::toBoolean(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return Value(SmallValue::fromPayload(this)).toBoolean(*esi);
}
double ValueRef::toNumber(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return Value(SmallValue::fromPayload(this)).toNumber(*esi);
}
double ValueRef::toLength(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return Value(SmallValue::fromPayload(this)).toLength(*esi);
}
int32_t ValueRef::toInt32(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return Value(SmallValue::fromPayload(this)).toInt32(*esi);
}
uint32_t ValueRef::toUint32(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return Value(SmallValue::fromPayload(this)).toUint32(*esi);
}
StringRef* ValueRef::toString(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return toRef(Value(SmallValue::fromPayload(this)).toString(*esi));
}
ObjectRef* ValueRef::toObject(ExecutionStateRef* es)
{
ExecutionState* esi = toImpl(es);
return toRef(Value(SmallValue::fromPayload(this)).toObject(*esi));
}
ValueRef::ValueIndex ValueRef::toIndex(ExecutionStateRef* state)
{
ExecutionState* esi = toImpl(state);
return Value(SmallValue::fromPayload(this)).toIndex(*esi);
}
uint32_t ValueRef::toArrayIndex(ExecutionStateRef* state)
{
uint32_t idx;
SmallValue s = SmallValue::fromPayload(this);
if (LIKELY(s.isInt32()))
return s.asInt32();
else {
ExecutionState* esi = toImpl(state);
return Value(s).toString(*esi)->tryToUseAsArrayIndex();
}
}
bool ValueRef::asBoolean()
{
return Value(SmallValue::fromPayload(this)).asBoolean();
}
double ValueRef::asNumber()
{
return Value(SmallValue::fromPayload(this)).asNumber();
}
int32_t ValueRef::asInt32()
{
return Value(SmallValue::fromPayload(this)).asInt32();
}
uint32_t ValueRef::asUint32()
{
return Value(SmallValue::fromPayload(this)).asUInt32();
}
StringRef* ValueRef::asString()
{
return toRef(Value(SmallValue::fromPayload(this)).asString());
}
ObjectRef* ValueRef::asObject()
{
return toRef(Value(SmallValue::fromPayload(this)).asObject());
}
FunctionObjectRef* ValueRef::asFunction()
{
return toRef(Value(SmallValue::fromPayload(this)).asFunction());
}
ArrayObjectRef* ArrayObjectRef::create(ExecutionStateRef* state)
{
return toRef(new ArrayObject(*toImpl(state)));
}
COMPILE_ASSERT((int)ErrorObject::Code::None == (int)ErrorObjectRef::Code::None, "");
COMPILE_ASSERT((int)ErrorObject::Code::ReferenceError == (int)ErrorObjectRef::Code::ReferenceError, "");
COMPILE_ASSERT((int)ErrorObject::Code::TypeError == (int)ErrorObjectRef::Code::TypeError, "");
COMPILE_ASSERT((int)ErrorObject::Code::SyntaxError == (int)ErrorObjectRef::Code::SyntaxError, "");
COMPILE_ASSERT((int)ErrorObject::Code::RangeError == (int)ErrorObjectRef::Code::RangeError, "");
COMPILE_ASSERT((int)ErrorObject::Code::URIError == (int)ErrorObjectRef::Code::URIError, "");
COMPILE_ASSERT((int)ErrorObject::Code::EvalError == (int)ErrorObjectRef::Code::EvalError, "");
ErrorObjectRef* ErrorObjectRef::create(ExecutionStateRef* state, ErrorObjectRef::Code code, StringRef* errorMessage)
{
return toRef(ErrorObject::createError(*toImpl(state), (ErrorObject::Code)code, toImpl(errorMessage)));
}
ReferenceErrorObjectRef* ReferenceErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new ReferenceErrorObject(*toImpl(state), toImpl(errorMessage)));
}
TypeErrorObjectRef* TypeErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new TypeErrorObject(*toImpl(state), toImpl(errorMessage)));
}
SyntaxErrorObjectRef* SyntaxErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new SyntaxErrorObject(*toImpl(state), toImpl(errorMessage)));
}
RangeErrorObjectRef* RangeErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new RangeErrorObject(*toImpl(state), toImpl(errorMessage)));
}
URIErrorObjectRef* URIErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new URIErrorObject(*toImpl(state), toImpl(errorMessage)));
}
EvalErrorObjectRef* EvalErrorObjectRef::create(ExecutionStateRef* state, StringRef* errorMessage)
{
return toRef(new EvalErrorObject(*toImpl(state), toImpl(errorMessage)));
}
#ifdef ESCARGOT_ENABLE_TYPEDARRAY
void ArrayBufferObjectRef::setMallocFunction(ArrayBufferObjectBufferMallocFunction fn)
{
g_arrayBufferObjectBufferMallocFunction = fn;
}
void ArrayBufferObjectRef::setFreeFunction(ArrayBufferObjectBufferFreeFunction fn)
{
g_arrayBufferObjectBufferFreeFunction = fn;
}
void ArrayBufferObjectRef::setMallocFunctionNeedsZeroFill(bool n)
{
g_arrayBufferObjectBufferMallocFunctionNeedsZeroFill = n;
}
ArrayBufferObjectRef* ArrayBufferObjectRef::create(ExecutionStateRef* state)
{
return toRef(new ArrayBufferObject(*toImpl(state)));
}
void ArrayBufferObjectRef::allocateBuffer(size_t bytelength)
{
toImpl(this)->allocateBuffer(bytelength);
}
void ArrayBufferObjectRef::attachBuffer(void* buffer, size_t bytelength)
{
toImpl(this)->attachBuffer(buffer, bytelength);
}
void ArrayBufferObjectRef::detachArrayBuffer()
{
toImpl(this)->detachArrayBuffer();
}
uint8_t* ArrayBufferObjectRef::rawBuffer()
{
return (uint8_t*)toImpl(this)->data();
}
unsigned ArrayBufferObjectRef::bytelength()
{
return toImpl(this)->bytelength();
}
ArrayBufferObjectRef* ArrayBufferViewRef::buffer()
{
return toRef(toImpl(this)->buffer());
}
uint8_t* ArrayBufferViewRef::rawBuffer()
{
return toImpl(this)->rawBuffer();
}
unsigned ArrayBufferViewRef::bytelength()
{
return toImpl(this)->bytelength();
}
#endif
#ifdef ESCARGOT_ENABLE_PROMISE
PromiseObjectRef* PromiseObjectRef::create(ExecutionStateRef* state)
{
return toRef(new PromiseObject(*toImpl(state)));
}
void PromiseObjectRef::fulfill(ExecutionStateRef* state, ValueRef* value)
{
toImpl(this)->fulfillPromise(*toImpl(state), toImpl(value));
}
void PromiseObjectRef::reject(ExecutionStateRef* state, ValueRef* reason)
{
toImpl(this)->rejectPromise(*toImpl(state), toImpl(reason));
}
#endif
ScriptParserRef::ScriptParserResult ScriptParserRef::parse(StringRef* script, StringRef* fileName)
{
auto result = toImpl(this)->parse(toImpl(script), toImpl(fileName));
if (result.m_error) {
return ScriptParserRef::ScriptParserResult(nullptr, toRef(result.m_error->message));
}
return ScriptParserRef::ScriptParserResult(toRef(result.m_script), StringRef::emptyString());
}
ValueRef* ScriptRef::execute(ExecutionStateRef* state)
{
return toRef(toImpl(this)->execute(*toImpl(state)));
}
}