Implement NamedPropertyHandler API to ObjectTemplate

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2020-07-20 21:51:41 +09:00 committed by Boram Bae
commit 25588dcb01
37 changed files with 831 additions and 254 deletions

View file

@ -72,82 +72,19 @@ bool NativeFunctionObject::isConstructor() const
return nativeCodeBlock()->isNativeConstructor();
}
template <bool isConstruct>
Value NativeFunctionObject::processNativeFunctionCall(ExecutionState& state, const Value& receiverSrc, const size_t argc, Value* argv, Optional<Object*> newTarget)
{
volatile int sp;
size_t currentStackBase = (size_t)&sp;
#ifdef STACK_GROWS_DOWN
if (UNLIKELY(state.stackLimit() > currentStackBase)) {
#else
if (UNLIKELY(state.stackLimit() < currentStackBase)) {
#endif
ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, "Maximum call stack size exceeded");
}
NativeCodeBlock* codeBlock = nativeCodeBlock();
Context* ctx = codeBlock->context();
bool isStrict = codeBlock->isStrict();
NativeFunctionPointer nativeFunc = codeBlock->nativeFunction();
size_t len = codeBlock->functionLength();
if (argc < len) {
Value* newArgv = (Value*)alloca(sizeof(Value) * len);
for (size_t i = 0; i < argc; i++) {
newArgv[i] = argv[i];
}
for (size_t i = argc; i < len; i++) {
newArgv[i] = Value();
}
argv = newArgv;
}
Value receiver = receiverSrc;
ExecutionState newState(ctx, &state, this, argc, argv, isStrict);
if (!isConstruct) {
// prepare receiver
if (UNLIKELY(!isStrict)) {
if (receiver.isUndefinedOrNull()) {
receiver = ctx->globalObject();
} else {
receiver = receiver.toObject(newState);
}
}
}
Value result;
if (isConstruct) {
result = nativeFunc(newState, receiver, argc, argv, newTarget);
if (UNLIKELY(!result.isObject())) {
ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Native Constructor must returns constructed new object");
}
} else {
ASSERT(!newTarget);
result = nativeFunc(newState, receiver, argc, argv, nullptr);
}
#ifdef ESCARGOT_DEBUGGER
Debugger::updateStopState(state.context()->debugger(), &newState, ESCARGOT_DEBUGGER_ALWAYS_STOP);
#endif /* ESCARGOT_DEBUGGER */
return result;
}
Value NativeFunctionObject::call(ExecutionState& state, const Value& thisValue, const size_t argc, NULLABLE Value* argv)
{
ASSERT(codeBlock()->isNativeCodeBlock());
return processNativeFunctionCall<false>(state, thisValue, argc, argv, nullptr);
}
Object* NativeFunctionObject::construct(ExecutionState& state, const size_t argc, NULLABLE Value* argv, Object* newTarget)
Value NativeFunctionObject::construct(ExecutionState& state, const size_t argc, NULLABLE Value* argv, Object* newTarget)
{
// Assert: Type(newTarget) is Object.
ASSERT(newTarget->isObject());
ASSERT(newTarget->isConstructor());
ASSERT(codeBlock()->isNativeCodeBlock());
Value result = processNativeFunctionCall<true>(state, Value(), argc, argv, newTarget);
return result.asObject();
return processNativeFunctionCall<true>(state, Value(), argc, argv, newTarget);
}
}