mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:38:11 +00:00
LibJS: Remove the non-standard put helper and replace it's usages
This removes all usages of the non-standard put helper method and replaces all of it's usages with the specification required alternative or with define_direct_property where appropriate.
This commit is contained in:
parent
53f70e5208
commit
e3ef241108
15 changed files with 40 additions and 49 deletions
|
@ -265,8 +265,8 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
||||||
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
||||||
object->put("column", JS::js_string(vm, sheet_object->m_sheet.column(position.value().column)));
|
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.value().column)), JS::default_attributes);
|
||||||
object->put("row", JS::Value((unsigned)position.value().row));
|
object->define_direct_property("row", JS::Value((unsigned)position.value().row), JS::default_attributes);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +295,8 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
|
||||||
auto position = current_cell->position();
|
auto position = current_cell->position();
|
||||||
|
|
||||||
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
auto object = JS::Object::create(global_object, global_object.object_prototype());
|
||||||
object->put("column", JS::js_string(vm, sheet_object->m_sheet.column(position.column)));
|
object->define_direct_property("column", JS::js_string(vm, sheet_object->m_sheet.column(position.column)), JS::default_attributes);
|
||||||
object->put("row", JS::Value((unsigned)position.row));
|
object->define_direct_property("row", JS::Value((unsigned)position.row), JS::default_attributes);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ Sheet::Sheet(Workbook& workbook)
|
||||||
JS::DeferGC defer_gc(m_workbook.interpreter().heap());
|
JS::DeferGC defer_gc(m_workbook.interpreter().heap());
|
||||||
m_global_object = m_workbook.interpreter().heap().allocate_without_global_object<SheetGlobalObject>(*this);
|
m_global_object = m_workbook.interpreter().heap().allocate_without_global_object<SheetGlobalObject>(*this);
|
||||||
global_object().initialize_global_object();
|
global_object().initialize_global_object();
|
||||||
global_object().put("workbook", m_workbook.workbook_object());
|
global_object().define_direct_property("workbook", m_workbook.workbook_object(), JS::default_attributes);
|
||||||
global_object().put("thisSheet", &global_object()); // Self-reference is unfortunate, but required.
|
global_object().define_direct_property("thisSheet", &global_object(), JS::default_attributes); // Self-reference is unfortunate, but required.
|
||||||
|
|
||||||
// Sadly, these have to be evaluated once per sheet.
|
// Sadly, these have to be evaluated once per sheet.
|
||||||
auto file_or_error = Core::File::open("/res/js/Spreadsheet/runtime.js", Core::OpenMode::ReadOnly);
|
auto file_or_error = Core::File::open("/res/js/Spreadsheet/runtime.js", Core::OpenMode::ReadOnly);
|
||||||
|
|
|
@ -38,7 +38,7 @@ Workbook::Workbook(NonnullRefPtrVector<Sheet>&& sheets)
|
||||||
, m_interpreter_scope(JS::VM::InterpreterExecutionScope(interpreter()))
|
, m_interpreter_scope(JS::VM::InterpreterExecutionScope(interpreter()))
|
||||||
{
|
{
|
||||||
m_workbook_object = interpreter().heap().allocate<WorkbookObject>(global_object(), *this);
|
m_workbook_object = interpreter().heap().allocate<WorkbookObject>(global_object(), *this);
|
||||||
global_object().put("workbook", workbook_object());
|
global_object().define_direct_property("workbook", workbook_object(), JS::default_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Workbook::set_filename(const String& filename)
|
bool Workbook::set_filename(const String& filename)
|
||||||
|
|
|
@ -89,9 +89,8 @@ Optional<JS::Value> DebuggerGlobalJSObject::debugger_to_js(const Debug::DebugInf
|
||||||
auto member_value = debugger_to_js(member);
|
auto member_value = debugger_to_js(member);
|
||||||
if (!member_value.has_value())
|
if (!member_value.has_value())
|
||||||
continue;
|
continue;
|
||||||
object->put(member.name, member_value.value(), {});
|
object->define_direct_property(member.name, member_value.value(), JS::default_attributes);
|
||||||
}
|
}
|
||||||
object->finish_writing_properties();
|
|
||||||
|
|
||||||
return JS::Value(object);
|
return JS::Value(object);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,8 @@ DebuggerVariableJSObject::~DebuggerVariableJSObject()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerVariableJSObject::internal_set(const JS::PropertyName& property_name, JS::Value value, JS::Value receiver)
|
bool DebuggerVariableJSObject::internal_set(const JS::PropertyName& property_name, JS::Value value, JS::Value)
|
||||||
{
|
{
|
||||||
if (m_is_writing_properties)
|
|
||||||
return Base::internal_set(property_name, value, receiver);
|
|
||||||
|
|
||||||
if (!property_name.is_string()) {
|
if (!property_name.is_string()) {
|
||||||
vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_name.to_string()));
|
vm().throw_exception<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_name.to_string()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,13 +25,11 @@ public:
|
||||||
virtual const char* class_name() const override { return m_variable_info.type_name.characters(); }
|
virtual const char* class_name() const override { return m_variable_info.type_name.characters(); }
|
||||||
|
|
||||||
bool internal_set(JS::PropertyName const&, JS::Value value, JS::Value receiver) override;
|
bool internal_set(JS::PropertyName const&, JS::Value value, JS::Value receiver) override;
|
||||||
void finish_writing_properties() { m_is_writing_properties = false; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebuggerGlobalJSObject& debugger_object() const;
|
DebuggerGlobalJSObject& debugger_object() const;
|
||||||
|
|
||||||
const Debug::DebugInfo::VariableInfo& m_variable_info;
|
const Debug::DebugInfo::VariableInfo& m_variable_info;
|
||||||
bool m_is_writing_properties { true };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ void IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
array->put(index, value);
|
array->create_data_property_or_throw(index, value);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ void GetById::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
void PutById::execute_impl(Bytecode::Interpreter& interpreter) const
|
void PutById::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object()))
|
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object()))
|
||||||
object->put(interpreter.current_executable().get_string(m_property), interpreter.accumulator());
|
object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
|
void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
|
@ -397,11 +397,11 @@ void Yield::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto yielded_value = interpreter.accumulator().value_or(js_undefined());
|
auto yielded_value = interpreter.accumulator().value_or(js_undefined());
|
||||||
auto object = JS::Object::create(interpreter.global_object(), nullptr);
|
auto object = JS::Object::create(interpreter.global_object(), nullptr);
|
||||||
object->put("result", yielded_value);
|
object->define_direct_property("result", yielded_value, JS::default_attributes);
|
||||||
if (m_continuation_label.has_value())
|
if (m_continuation_label.has_value())
|
||||||
object->put("continuation", Value(static_cast<double>(reinterpret_cast<u64>(&m_continuation_label->block()))));
|
object->define_direct_property("continuation", Value(static_cast<double>(reinterpret_cast<u64>(&m_continuation_label->block()))), JS::default_attributes);
|
||||||
else
|
else
|
||||||
object->put("continuation", Value(0));
|
object->define_direct_property("continuation", Value(0), JS::default_attributes);
|
||||||
interpreter.do_return(object);
|
interpreter.do_return(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ void PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object());
|
auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object());
|
||||||
if (interpreter.vm().exception())
|
if (interpreter.vm().exception())
|
||||||
return;
|
return;
|
||||||
object->put(property_key, interpreter.accumulator());
|
object->set(property_key, interpreter.accumulator(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,11 +110,11 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, ScopeType scope_type,
|
||||||
if (is_program_node && declaration.declaration_kind() == DeclarationKind::Var) {
|
if (is_program_node && declaration.declaration_kind() == DeclarationKind::Var) {
|
||||||
declarator.target().visit(
|
declarator.target().visit(
|
||||||
[&](const NonnullRefPtr<Identifier>& id) {
|
[&](const NonnullRefPtr<Identifier>& id) {
|
||||||
global_object.put(id->string(), js_undefined());
|
global_object.define_direct_property(id->string(), js_undefined(), JS::Attribute::Writable | JS::Attribute::Enumerable);
|
||||||
},
|
},
|
||||||
[&](const NonnullRefPtr<BindingPattern>& binding) {
|
[&](const NonnullRefPtr<BindingPattern>& binding) {
|
||||||
binding->for_each_bound_name([&](const auto& name) {
|
binding->for_each_bound_name([&](const auto& name) {
|
||||||
global_object.put(name, js_undefined());
|
global_object.define_direct_property(name, js_undefined(), JS::Attribute::Writable | JS::Attribute::Enumerable);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (exception())
|
if (exception())
|
||||||
|
|
|
@ -369,7 +369,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto new_length_value = Value((i32)new_length);
|
auto new_length_value = Value((i32)new_length);
|
||||||
this_object->put(vm.names.length, new_length_value);
|
this_object->set(vm.names.length, new_length_value, true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return new_length_value;
|
return new_length_value;
|
||||||
|
@ -420,7 +420,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this_object->put(vm.names.length, Value(new_length));
|
this_object->set(vm.names.length, Value(new_length), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return Value(new_length);
|
return Value(new_length);
|
||||||
|
@ -442,7 +442,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
this_object->put(vm.names.length, Value(0));
|
this_object->set(vm.names.length, Value(0), true);
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
auto index = length - 1;
|
auto index = length - 1;
|
||||||
|
@ -452,7 +452,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
|
||||||
this_object->delete_property_or_throw(index);
|
this_object->delete_property_or_throw(index);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
this_object->put(vm.names.length, Value((i32)index));
|
this_object->set(vm.names.length, Value((i32)index), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return element;
|
return element;
|
||||||
|
@ -468,7 +468,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
this_object->put(vm.names.length, Value(0));
|
this_object->set(vm.names.length, Value(0), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
|
@ -501,7 +501,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
this_object->put(vm.names.length, Value(length - 1));
|
this_object->set(vm.names.length, Value(length - 1), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return first;
|
return first;
|
||||||
|
@ -693,7 +693,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
new_array->put(vm.names.length, Value(n));
|
new_array->set(vm.names.length, Value(n), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
return Value(new_array);
|
return Value(new_array);
|
||||||
|
@ -769,7 +769,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_array->put(vm.names.length, Value(index));
|
new_array->set(vm.names.length, Value(index), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -1675,7 +1675,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removed_elements->put(vm.names.length, Value(actual_delete_count));
|
removed_elements->set(vm.names.length, Value(actual_delete_count), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -1725,7 +1725,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this_object->put(vm.names.length, Value((i32)new_length));
|
this_object->set(vm.names.length, Value((i32)new_length), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -1771,7 +1771,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
|
||||||
to = min(relative_end, length);
|
to = min(relative_end, length);
|
||||||
|
|
||||||
for (size_t i = from; i < to; i++) {
|
for (size_t i = from; i < to; i++) {
|
||||||
this_object->put(i, vm.argument(0));
|
this_object->set(i, vm.argument(0), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1988,7 +1988,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
|
||||||
auto from_value = this_object->get(from_i);
|
auto from_value = this_object->get(from_i);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
this_object->put(to_i, from_value);
|
this_object->set(to_i, from_value, true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -73,10 +73,10 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto result = Object::create(global_object, global_object.object_prototype());
|
auto result = Object::create(global_object, global_object.object_prototype());
|
||||||
result->put("value", previous_generated_value);
|
result->define_direct_property("value", previous_generated_value, JS::default_attributes);
|
||||||
|
|
||||||
if (m_done) {
|
if (m_done) {
|
||||||
result->put("done", Value(true));
|
result->define_direct_property("done", Value(true), JS::default_attributes);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
|
||||||
if (!next_block) {
|
if (!next_block) {
|
||||||
// The generator has terminated, now we can simply return done=true.
|
// The generator has terminated, now we can simply return done=true.
|
||||||
m_done = true;
|
m_done = true;
|
||||||
result->put("done", Value(true));
|
result->define_direct_property("done", Value(true), JS::default_attributes);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +115,8 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V
|
||||||
|
|
||||||
m_done = generated_continuation(m_previous_value) == nullptr;
|
m_done = generated_continuation(m_previous_value) == nullptr;
|
||||||
|
|
||||||
result->put("value", generated_value(m_previous_value));
|
result->define_direct_property("value", generated_value(m_previous_value), JS::default_attributes);
|
||||||
result->put("done", Value(m_done));
|
result->define_direct_property("done", Value(m_done), JS::default_attributes);
|
||||||
|
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -123,9 +123,6 @@ public:
|
||||||
|
|
||||||
// Non-standard methods
|
// Non-standard methods
|
||||||
|
|
||||||
// - Helpers using old, non-standard names but wrapping the standard methods.
|
|
||||||
// FIXME: Update all the code relying on these and remove them.
|
|
||||||
bool put(PropertyName const& property_name, Value value, Value receiver = {}) { return internal_set(property_name, value, receiver.value_or(this)); }
|
|
||||||
Value get_without_side_effects(const PropertyName&) const;
|
Value get_without_side_effects(const PropertyName&) const;
|
||||||
|
|
||||||
void define_direct_property(PropertyName const& property_name, Value value, PropertyAttributes attributes) { storage_set(property_name, { value, attributes }); };
|
void define_direct_property(PropertyName const& property_name, Value value, PropertyAttributes attributes) { storage_set(property_name, { value, attributes }); };
|
||||||
|
|
|
@ -34,7 +34,7 @@ Optional<Variable> ObjectEnvironment::get_from_environment(FlyString const& name
|
||||||
|
|
||||||
bool ObjectEnvironment::put_into_environment(FlyString const& name, Variable variable)
|
bool ObjectEnvironment::put_into_environment(FlyString const& name, Variable variable)
|
||||||
{
|
{
|
||||||
return m_binding_object.put(name, variable.value);
|
return m_binding_object.set(name, variable.value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectEnvironment::delete_from_environment(FlyString const& name)
|
bool ObjectEnvironment::delete_from_environment(FlyString const& name)
|
||||||
|
|
|
@ -180,7 +180,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::of)
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
for (size_t k = 0; k < length; ++k) {
|
for (size_t k = 0; k < length; ++k) {
|
||||||
auto success = new_object->put(k, vm.argument(k));
|
auto success = new_object->set(k, vm.argument(k), true);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
|
@ -160,7 +160,7 @@ void VM::set_variable(const FlyString& name, Value value, GlobalObject& global_o
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_object.put(name, value);
|
global_object.set(name, value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VM::delete_variable(FlyString const& name)
|
bool VM::delete_variable(FlyString const& name)
|
||||||
|
@ -298,7 +298,7 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global
|
||||||
continue;
|
continue;
|
||||||
if (seen_names.contains(object_property.key.to_display_string()))
|
if (seen_names.contains(object_property.key.to_display_string()))
|
||||||
continue;
|
continue;
|
||||||
rest_object->put(object_property.key, object->get(object_property.key));
|
rest_object->set(object_property.key, object->get(object_property.key), true);
|
||||||
if (exception())
|
if (exception())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,8 +329,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
||||||
auto instance_object = vm.heap().allocate<WebAssemblyInstanceObject>(global_object, global_object, result.value());
|
auto instance_object = vm.heap().allocate<WebAssemblyInstanceObject>(global_object, global_object, result.value());
|
||||||
if (should_return_module) {
|
if (should_return_module) {
|
||||||
auto object = JS::Object::create(global_object, nullptr);
|
auto object = JS::Object::create(global_object, nullptr);
|
||||||
object->put("module", vm.heap().allocate<WebAssemblyModuleObject>(global_object, global_object, s_compiled_modules.size() - 1));
|
object->define_direct_property("module", vm.heap().allocate<WebAssemblyModuleObject>(global_object, global_object, s_compiled_modules.size() - 1), JS::default_attributes);
|
||||||
object->put("instance", instance_object);
|
object->define_direct_property("instance", instance_object, JS::default_attributes);
|
||||||
promise->fulfill(object);
|
promise->fulfill(object);
|
||||||
} else {
|
} else {
|
||||||
promise->fulfill(instance_object);
|
promise->fulfill(instance_object);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue