Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new function #128

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion ecmascript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,41 @@ ECMAScript::ECMAScript() {
ECMAScript::~ECMAScript() {
}

bool ECMAScript::can_instance() const {
Variant ECMAScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
ECMAScriptBinder *binder = ECMAScriptLanguage::get_thread_binder(Thread::get_caller_id());
const ECMAClassInfo *cls = NULL;
ECMAscriptScriptError ecma_err;
if (!bytecode.empty()) {
cls = binder->parse_ecma_class(bytecode, script_path, false, &ecma_err);
} else {
cls = binder->parse_ecma_class(code, script_path, false, &ecma_err);
}
ERR_FAIL_NULL_V_MSG(cls, NULL, vformat("Cannot parse class from %s", get_script_path()));

Object *object = ClassDB::instance(cls->native_class->name);
ERR_FAIL_COND_V_MSG(!object, Variant(), "Class type: '" + String(class_name) + "' is not instantiable.");

ECMAScriptGCHandler ecma_instance = binder->create_ecma_instance_for_godot_object_args(cls, object, p_args, p_argcount);
ERR_FAIL_NULL_V(ecma_instance.ecma_object, NULL);

ECMAScriptInstance *instance = memnew(ECMAScriptInstance);
instance->script = Ref<ECMAScript>(this);
instance->owner = object;
instance->binder = binder;
instance->ecma_object = ecma_instance;
instance->ecma_class = cls;
instance->owner->set_script_instance(instance);
instances.insert(object);

Reference *ref = Object::cast_to<Reference>(object);
if (ref) {
return REF(ref);
} else {
return object;
}
}

bool ECMAScript::can_instance() const {
#ifdef TOOLS_ENABLED
return is_valid() && (is_tool() || ScriptServer::is_scripting_enabled());
#else
Expand Down Expand Up @@ -238,6 +271,7 @@ bool ECMAScript::is_valid() const {
}

void ECMAScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &ECMAScript::_new);
}

RES ResourceFormatLoaderECMAScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
Expand Down
1 change: 1 addition & 0 deletions ecmascript.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ECMAScript : public Script {
static void _bind_methods();

public:
Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
virtual bool can_instance() const;

virtual bool inherits_script(const Ref<Script> &p_script) const { return false; }
Expand Down
1 change: 1 addition & 0 deletions ecmascript_binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class ECMAScriptBinder {
virtual const ECMAClassInfo *parse_ecma_class(const String &p_code, const String &p_path, bool ignore_cacehe, ECMAscriptScriptError *r_error) = 0;
virtual const ECMAClassInfo *parse_ecma_class(const Vector<uint8_t> &p_bytecode, const String &p_path, bool ignore_cacehe, ECMAscriptScriptError *r_error) = 0;

virtual ECMAScriptGCHandler create_ecma_instance_for_godot_object_args(const ECMAClassInfo *p_class, Object *p_object, const Variant **p_args, int p_argcount) = 0;
virtual ECMAScriptGCHandler create_ecma_instance_for_godot_object(const ECMAClassInfo *p_class, Object *p_object) = 0;
virtual Variant call_method(const ECMAScriptGCHandler &p_object, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) = 0;
virtual bool get_instance_property(const ECMAScriptGCHandler &p_object, const StringName &p_name, Variant &r_ret) = 0;
Expand Down
32 changes: 32 additions & 0 deletions quickjs/quickjs_binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,38 @@ void QuickJSBinder::get_own_property_names(JSContext *ctx, JSValue p_object, Set
js_free_rt(JS_GetRuntime(ctx), props);
}

ECMAScriptGCHandler QuickJSBinder::create_ecma_instance_for_godot_object_args(const ECMAClassInfo *p_class, Object *p_object, const Variant **p_args, int p_argcount) {

ERR_FAIL_NULL_V(p_object, ECMAScriptGCHandler());
ERR_FAIL_NULL_V(p_class, ECMAScriptGCHandler());

ECMAScriptGCHandler *bind = BINDING_DATA_FROM_GD(ctx, p_object);
ERR_FAIL_NULL_V(bind, ECMAScriptGCHandler());

JSValue constructor = JS_MKPTR(JS_TAG_OBJECT, p_class->constructor.ecma_object);
JSValue object = JS_MKPTR(JS_TAG_OBJECT, bind->ecma_object);


JSValue *argv = NULL;
argv = memnew_arr(JSValue, p_argcount);
for (int i = 0; i < p_argcount; ++i) {
argv[i] = variant_to_var(ctx, *p_args[i]);
}


JS_CallConstructor2(ctx, constructor, object, p_argcount, argv);
if (JS_SetPrototype(ctx, object, JS_MKPTR(JS_TAG_OBJECT, p_class->prototype.ecma_object)) < 0) {
JSValue e = JS_GetException(ctx);
ECMAscriptScriptError error;
dump_exception(ctx, e, &error);
JS_FreeValue(ctx, e);
bind->ecma_object = NULL;
ERR_FAIL_V_MSG(*bind, vformat("Cannot create instance from ECMAScript class '%s'\n%s", p_class->class_name, error_to_string(error)));
}
//initialize_properties(ctx, p_class, object);
return *bind;
}

ECMAScriptGCHandler QuickJSBinder::create_ecma_instance_for_godot_object(const ECMAClassInfo *p_class, Object *p_object) {

ERR_FAIL_NULL_V(p_object, ECMAScriptGCHandler());
Expand Down
1 change: 1 addition & 0 deletions quickjs/quickjs_binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ class QuickJSBinder : public ECMAScriptBinder {
virtual const ECMAClassInfo *parse_ecma_class(const Vector<uint8_t> &p_bytecode, const String &p_path, bool ignore_cacehe, ECMAscriptScriptError *r_error);
const ECMAClassInfo *parse_ecma_class_from_module(ModuleCache *p_module, const String &p_path, ECMAscriptScriptError *r_error);

virtual ECMAScriptGCHandler create_ecma_instance_for_godot_object_args(const ECMAClassInfo *p_class, Object *p_object, const Variant **p_args, int p_argcount);
virtual ECMAScriptGCHandler create_ecma_instance_for_godot_object(const ECMAClassInfo *p_class, Object *p_object);
virtual Variant call_method(const ECMAScriptGCHandler &p_object, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
virtual bool get_instance_property(const ECMAScriptGCHandler &p_object, const StringName &p_name, Variant &r_ret);
Expand Down