mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
2. VariableDeclaratorNode does not affect execute result 3. optimize Object get, set in interpreter Signed-off-by: seonghyun kim <sh8281.kim@samsung.com>
147 lines
8.4 KiB
C++
147 lines
8.4 KiB
C++
#include "Escargot.h"
|
|
#include "GlobalObject.h"
|
|
#include "Context.h"
|
|
|
|
namespace Escargot {
|
|
|
|
static Value builtinObjectConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, bool isNewExpression)
|
|
{
|
|
Value value = argv[0];
|
|
if (value.isUndefined() || value.isNull()) {
|
|
return new Object(state);
|
|
} else {
|
|
return value.toObject(state);
|
|
}
|
|
}
|
|
|
|
static Value builtinObjectToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, bool isNewExpression)
|
|
{
|
|
if (thisValue.isUndefined()) {
|
|
return new ASCIIString("[object Undefined]");
|
|
} else if (thisValue.isNull()) {
|
|
return new ASCIIString("[object Null]");
|
|
}
|
|
|
|
Object* thisObject = thisValue.toObject(state);
|
|
if (thisObject->isFunctionObject()) {
|
|
return AtomicString(state, "[object Function]").string();
|
|
} else if (thisObject->isArrayObject()) {
|
|
return AtomicString(state, "[object Array]").string();
|
|
} else if (thisObject->isStringObject()) {
|
|
return AtomicString(state, "[object String]").string();
|
|
} else if (thisObject->isFunctionObject()) {
|
|
return AtomicString(state, "[object Function]").string();
|
|
} else if (thisObject->isErrorObject()) {
|
|
return AtomicString(state, "[object Error]").string();
|
|
} else if (thisObject->isBooleanObject()) {
|
|
return AtomicString(state, "[object Boolean]").string();
|
|
} else if (thisObject->isNumberObject()) {
|
|
return AtomicString(state, "[object Number]").string();
|
|
} else if (thisObject->isDateObject()) {
|
|
return AtomicString(state, "[object Date]").string();
|
|
} else if (thisObject->isRegExpObject()) {
|
|
return AtomicString(state, "[object RegExp]").string();
|
|
} /*else if (thisObject->isESMathObject()) {
|
|
return AtomicString(state, "[object Math]").string();
|
|
} else if (thisObject->isESJSONObject()) {
|
|
return AtomicString(state, "[object JSON]").string();
|
|
#ifdef USE_ES6_FEATURE
|
|
} else if (thisObject->isESTypedArrayObject()) {
|
|
ASCIIString ret = "[object ";
|
|
ESValue ta_constructor = thisObject->get(strings->constructor.string()).string();
|
|
// ALWAYS created from new expression
|
|
ASSERT(ta_constructor.isESPointer() && ta_constructor.asESPointer()->isESObject()).string();
|
|
ESValue ta_name = ta_constructor.asESPointer()->asESObject()->get(strings->name.string()).string();
|
|
ret.append(ta_name.toString()->asciiData()).string();
|
|
ret.append("]").string();
|
|
return AtomicString(state, ret.data()).string();
|
|
} else if (thisObject->isESArrayBufferObject()) {
|
|
return AtomicString(state, "[object ArrayBuffer]").string();
|
|
} else if (thisObject->isESDataViewObject()) {
|
|
return AtomicString(state, "[object DataView]").string();
|
|
} else if (thisObject->isESPromiseObject()) {
|
|
return AtomicString(state, "[object Promise]").string();
|
|
#endif
|
|
} else if (thisObject->isESArgumentsObject()) {
|
|
return AtomicString(state, "[object Arguments]").string();
|
|
}*/ else if (thisObject->isGlobalObject()) {
|
|
return AtomicString(state, "[object global]").string();
|
|
}
|
|
return AtomicString(state, "[object Object]").string();
|
|
}
|
|
|
|
static Value builtinObjectHasOwnProperty(ExecutionState& state, Value thisValue, size_t argc, Value* argv, bool isNewExpression)
|
|
{
|
|
String* keyString = argv[0].toPrimitive(state, Value::PrimitiveTypeHint::PreferString).toString(state);
|
|
Object* obj = thisValue.toObject(state);
|
|
return Value(obj->hasOwnProperty(state, ObjectPropertyName(state, keyString)));
|
|
}
|
|
|
|
inline Value objectDefineProperties(ExecutionState& state, Value object, Value properties)
|
|
{
|
|
const StaticStrings* strings = &state.context()->staticStrings();
|
|
if (!object.isObject())
|
|
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->Object.string(), false, strings->defineProperty.string(), errorMessage_GlobalObject_FirstArgumentNotObject);
|
|
Object* props = properties.toObject(state);
|
|
std::vector<std::pair<ObjectPropertyName, ObjectPropertyDescriptor> > descriptors;
|
|
props->enumeration(state, [&](const ObjectPropertyName& name, const ObjectStructurePropertyDescriptor& desc) -> bool {
|
|
auto propDesc = props->getOwnProperty(state, name);
|
|
if (propDesc.hasValue() && !propDesc.value().isUndefined() && desc.isEnumerable()) {
|
|
Value propVal = propDesc.value();
|
|
if (!propVal.isObject())
|
|
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->Object.string(), false, strings->defineProperty.string(), errorMessage_GlobalObject_DescriptorNotObject);
|
|
descriptors.push_back(std::make_pair(name, ObjectPropertyDescriptor(state, propVal.toObject(state))));
|
|
}
|
|
return true;
|
|
});
|
|
for (auto it : descriptors) {
|
|
object.asObject()->defineOwnPropertyThrowsException(state, it.first, it.second);
|
|
}
|
|
return object;
|
|
}
|
|
|
|
static Value builtinObjectCreate(ExecutionState& state, Value thisValue, size_t argc, Value* argv, bool isNewExpression)
|
|
{
|
|
if (!argv[0].isObject() && !argv[0].isNull())
|
|
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().Object.string(), false, state.context()->staticStrings().create.string(), errorMessage_GlobalObject_FirstArgumentNotObjectAndNotNull);
|
|
Object* obj = new Object(state);
|
|
if (argv[0].isNull())
|
|
obj->setPrototype(state, Value(Value::Null));
|
|
else
|
|
obj->setPrototype(state, argv[0]);
|
|
|
|
if (!argv[1].isUndefined())
|
|
return objectDefineProperties(state, obj, argv[1]);
|
|
return obj;
|
|
}
|
|
|
|
|
|
void GlobalObject::installObject(ExecutionState& state)
|
|
{
|
|
FunctionObject* emptyFunction = m_functionPrototype;
|
|
m_object = new FunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Object, builtinObjectConstructor, 1, [](ExecutionState& state, size_t argc, Value* argv) -> Object* {
|
|
return new Object(state);
|
|
}));
|
|
m_object->markThisObjectDontNeedStructureTransitionTable(state);
|
|
m_object->setPrototype(state, emptyFunction);
|
|
// TODO m_object->defineAccessorProperty(strings->prototype.string(), ESVMInstance::currentInstance()->functionPrototypeAccessorData(), false, false, false);
|
|
m_object->setFunctionPrototype(state, m_objectPrototype);
|
|
// $19.1.2.2 Object.create (O [,Properties])
|
|
m_object->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().create),
|
|
ObjectPropertyDescriptor(new FunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().create, builtinObjectCreate, 2, nullptr, NativeFunctionInfo::Strict)),
|
|
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
|
m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().constructor),
|
|
ObjectPropertyDescriptor(m_object, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
|
|
|
m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().toString),
|
|
ObjectPropertyDescriptor(new FunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().toString, builtinObjectToString, 0, nullptr, NativeFunctionInfo::Strict)),
|
|
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
|
|
|
// $19.1.3.2 Object.prototype.hasOwnProperty(V)
|
|
m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().hasOwnProperty),
|
|
ObjectPropertyDescriptor(new FunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().toString, builtinObjectHasOwnProperty, 1, nullptr, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
|
|
|
defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Object),
|
|
ObjectPropertyDescriptor(m_object, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
|
|
}
|
|
}
|