JSModuleEnvironment.cpp [plain text]
#include "config.h"
#include "JSModuleEnvironment.h"
#include "AbstractModuleRecord.h"
#include "Interpreter.h"
#include "JSCInlines.h"
#include "JSFunction.h"
using namespace std;
namespace JSC {
const ClassInfo JSModuleEnvironment::s_info = { "JSModuleEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSModuleEnvironment) };
JSModuleEnvironment* JSModuleEnvironment::create(
VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable, JSValue initialValue, AbstractModuleRecord* moduleRecord)
{
JSModuleEnvironment* result =
new (
NotNull,
allocateCell<JSModuleEnvironment>(vm.heap, JSModuleEnvironment::allocationSize(symbolTable)))
JSModuleEnvironment(vm, structure, currentScope, symbolTable);
result->finishCreation(vm, initialValue, moduleRecord);
return result;
}
void JSModuleEnvironment::finishCreation(VM& vm, JSValue initialValue, AbstractModuleRecord* moduleRecord)
{
Base::finishCreation(vm, initialValue);
this->moduleRecordSlot().set(vm, this, moduleRecord);
}
void JSModuleEnvironment::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell);
Base::visitChildren(thisObject, visitor);
visitor.appendValues(thisObject->variables(), thisObject->symbolTable()->scopeSize());
visitor.append(thisObject->moduleRecordSlot());
}
bool JSModuleEnvironment::getOwnPropertySlot(JSObject* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell);
AbstractModuleRecord::Resolution resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid()));
if (resolution.type == AbstractModuleRecord::Resolution::Type::Resolved) {
JSModuleEnvironment* importedModuleEnvironment = resolution.moduleRecord->moduleEnvironment();
PropertySlot redirectSlot(importedModuleEnvironment, PropertySlot::InternalMethodType::Get);
bool result = importedModuleEnvironment->methodTable(vm)->getOwnPropertySlot(importedModuleEnvironment, exec, resolution.localName, redirectSlot);
ASSERT_UNUSED(result, result);
ASSERT(redirectSlot.isValue());
JSValue value = redirectSlot.getValue(exec, resolution.localName);
ASSERT_UNUSED(scope, !scope.exception());
slot.setValue(thisObject, redirectSlot.attributes(), value);
return true;
}
return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
void JSModuleEnvironment::getOwnNonIndexPropertyNames(JSObject* cell, ExecState* exec, PropertyNameArray& propertyNamesArray, EnumerationMode mode)
{
JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell);
if (propertyNamesArray.includeStringProperties()) {
for (const auto& pair : thisObject->moduleRecord()->importEntries()) {
const AbstractModuleRecord::ImportEntry& importEntry = pair.value;
if (!importEntry.isNamespace(exec->vm()))
propertyNamesArray.add(importEntry.localName);
}
}
return Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNamesArray, mode);
}
bool JSModuleEnvironment::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell);
AbstractModuleRecord::Resolution resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid()));
if (resolution.type == AbstractModuleRecord::Resolution::Type::Resolved) {
throwTypeError(exec, scope, ASCIILiteral(ReadonlyPropertyWriteError));
return false;
}
return Base::put(thisObject, exec, propertyName, value, slot);
}
bool JSModuleEnvironment::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
{
JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell);
AbstractModuleRecord::Resolution resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid()));
if (resolution.type == AbstractModuleRecord::Resolution::Type::Resolved)
return false;
return Base::deleteProperty(thisObject, exec, propertyName);
}
}