Пример #1
0
void PushWeakObject(duk_context* ctx, Object* object)
{
    if (!object)
    {
        duk_push_null(ctx);
        return;
    }

    duk_push_heap_stash(ctx);

    // Check if the wrapper for the object already exists in stash
    // This is required so that comparisons of object references (e.g. against the me property) work properly
    if (duk_has_prop_index(ctx, -1, (size_t)object))
    {
        duk_get_prop_index(ctx, -1, (size_t)object);
        WeakPtr<Object>* oldPtr = GetWeakPtr(ctx, -1);
        if (oldPtr && oldPtr->Get() == object)
        {
            duk_remove(ctx, -2); // Remove stash
            return;
        }
        else
            duk_pop(ctx); // Valid existing wrapper not found
    }

    duk_push_object(ctx);
    WeakPtr<Object>* ptr = new WeakPtr<Object>(object);
    duk_push_pointer(ctx, ptr);
    duk_put_prop_string(ctx, -2, "\xff""weak");
    duk_push_c_function(ctx, WeakPtr_Finalizer, 1);
    duk_set_finalizer(ctx, -2);

    // Set prototype. If not found, use base class prototype (e.g. IComponent)
    duk_get_global_string(ctx, object->GetTypeName().CString());
    if (!duk_is_object(ctx, -1))
    {
        duk_pop(ctx);
        duk_get_global_string(ctx, object->GetTypeInfo()->GetBaseTypeInfo()->GetTypeName().CString());
    }
    duk_get_prop_string(ctx, -1, "prototype");
    duk_set_prototype(ctx, -3);
    duk_pop(ctx);

    // Proxied property access handling for scene, entity & component
    if (object->GetType() == Scene::GetTypeStatic())
        SetupProxy(ctx, SceneProxyFunctions);
    if (object->GetType() == Entity::GetTypeStatic())
        SetupProxy(ctx, EntityProxyFunctions);
    else if (dynamic_cast<IComponent*>(object))
        SetupProxy(ctx, ComponentProxyFunctions);

    // Store to stash
    duk_dup(ctx, -1);
    duk_put_prop_index(ctx, -3, (size_t)object);
    duk_remove(ctx, -2); // Remove stash
}
Пример #2
0
static duk_ret_t duk__console_log_helper(duk_context *ctx, const char *error_name) {
	duk_idx_t i, n;

	n = duk_get_top(ctx);

	duk_get_global_string(ctx, "console");
	duk_get_prop_string(ctx, -1, "format");

	for (i = 0; i < n; i++) {
		if (duk_check_type_mask(ctx, i, DUK_TYPE_MASK_OBJECT)) {
			/* Slow path formatting. */
			duk_dup(ctx, -1);  /* console.format */
			duk_dup(ctx, i);
			duk_call(ctx, 1);
			duk_replace(ctx, i);  /* arg[i] = console.format(arg[i]); */
		}
	}

	duk_pop_2(ctx);

	duk_push_string(ctx, " ");
	duk_insert(ctx, 0);
	duk_join(ctx, n);

	if (error_name) {
		duk_push_error_object(ctx, DUK_ERR_ERROR, "%s", duk_require_string(ctx, -1));
		duk_push_string(ctx, "name");
		duk_push_string(ctx, error_name);
		duk_def_prop(ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_VALUE);  /* to get e.g. 'Trace: 1 2 3' */
		duk_get_prop_string(ctx, -1, "stack");
	}

	printf("%s\n", duk_to_string(ctx, -1));
	return 0;
}
Пример #3
0
bool StyleContext::evalFilter(FunctionID _id) const {
    if (!duk_get_global_string(m_ctx, FUNC_ID)) {
        logMsg("Error: evalFilterFn - functions not initialized\n");
        return false;
    }

    if (!duk_get_prop_index(m_ctx, -1, _id)) {
        logMsg("Error: evalFilterFn - function %d not set\n", _id);
    }

    if (duk_pcall(m_ctx, 0) != 0) {
        logMsg("Error: evalFilterFn: %s\n", duk_safe_to_string(m_ctx, -1));
    }

    bool result = false;

    if (duk_is_boolean(m_ctx, -1)) {
        result = duk_get_boolean(m_ctx, -1);
    }

    // pop result
    duk_pop(m_ctx);
    // pop fns obj
    duk_pop(m_ctx);

    DUMP("evalFilterFn\n");
    return result;
}
Пример #4
0
void
_gum_duk_push_proxy (duk_context * ctx,
                     duk_idx_t target,
                     duk_c_function getter,
                     duk_c_function setter)
{
  duk_dup (ctx, target);

  duk_get_global_string (ctx, "Proxy");
  duk_dup (ctx, -2);
  duk_push_object (ctx);

  if (getter != NULL)
  {
    duk_push_c_function (ctx, getter, 3);
    duk_put_prop_string (ctx, -2, "get");
  }

  if (setter != NULL)
  {
    duk_push_c_function (ctx, setter, 4);
    duk_put_prop_string (ctx, -2, "set");
  }

  duk_new (ctx, 2);

  duk_swap_top (ctx, -2);
  duk_pop (ctx);
}
Пример #5
0
duk_ret_t dukky_before_unload_event___proto(duk_context *ctx)
{
	/* Set this prototype's prototype (left-parent) */
	/* get prototype */
	duk_get_global_string(ctx, dukky_magic_string_prototypes);
	duk_get_prop_string(ctx, -1, "\xFF\xFFNETSURF_DUKTAPE_PROTOTYPE_EVENT");
	duk_replace(ctx, -2);
	duk_set_prototype(ctx, 0);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "returnValue");
	duk_push_c_function(ctx, dukky_before_unload_event_returnValue_getter, 0);
	duk_push_c_function(ctx, dukky_before_unload_event_returnValue_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Set the destructor */
	duk_dup(ctx, 0);
	duk_push_c_function(ctx, dukky_before_unload_event___destructor, 1);
	duk_set_finalizer(ctx, -2);
	duk_pop(ctx);

	/* Set the constructor */
	duk_dup(ctx, 0);
	duk_push_c_function(ctx, dukky_before_unload_event___constructor, 2);
	duk_put_prop_string(ctx, -2, "\xFF\xFFNETSURF_DUKTAPE_INIT");
	duk_pop(ctx);

	return 1; /* The prototype object */
}
Пример #6
0
bool StyleContext::evalFunction(FunctionID id) {
    // Get all functions (array) in context
    if (!duk_get_global_string(m_ctx, FUNC_ID)) {
        LOGE("EvalFilterFn - functions array not initialized");
        duk_pop(m_ctx); // pop [undefined] sitting at stack top
        return false;
    }

    // Get function at index `id` from functions array, put it at stack top
    if (!duk_get_prop_index(m_ctx, -1, id)) {
        LOGE("EvalFilterFn - function %d not set", id);
        duk_pop(m_ctx); // pop "undefined" sitting at stack top
        duk_pop(m_ctx); // pop functions (array) now sitting at stack top
        return false;
    }

    // pop fns array
    duk_remove(m_ctx, -2);

    // call popped function (sitting at stack top), evaluated value is put on stack top
    if (duk_pcall(m_ctx, 0) != 0) {
        LOGE("EvalFilterFn: %s", duk_safe_to_string(m_ctx, -1));
        duk_pop(m_ctx);
        return false;
    }

    return true;
}
void jsapi_init_filesystem(JSVM* vm)
{
    duk_context* ctx = vm->GetJSContext();

    duk_get_global_string(ctx, "Atomic");

    duk_push_c_function(ctx, Atomic_SplitPath, 1);
    duk_put_prop_string(ctx, -2, "splitPath");

    duk_push_c_function(ctx, Atomic_AddTrailingSlash, 1);
    duk_put_prop_string(ctx, -2, "addTrailingSlash");

    duk_push_c_function(ctx, Atomic_GetParentPath, 1);
    duk_put_prop_string(ctx, -2, "getParentPath");

    duk_push_c_function(ctx, Atomic_GetExtenstion, 1);
    duk_put_prop_string(ctx, -2, "getExtension");

    duk_pop(ctx); // pop Atomic object

    js_class_get_prototype(ctx, "Atomic", "FileSystem");
    duk_push_c_function(ctx, FileSystem_ScanDir, 4);
    duk_put_prop_string(ctx, -2, "scanDir");
    duk_pop(ctx);

}
Пример #8
0
void jsapi_init_ui(JSVM* vm)
{
    duk_context* ctx = vm->GetJSContext();

    // UI class object
    duk_get_global_string(ctx, "Atomic");
    duk_get_prop_string(ctx, -1, "UI");

    duk_push_c_function(ctx, UI_DebugGetWrappedWidgetCount, 0);
    duk_put_prop_string(ctx, -2, "debugGetWrappedWidgetCount");

    duk_push_c_function(ctx, UI_DebugGetUIKeepAliveCount, 0);
    duk_put_prop_string(ctx, -2, "debugGetUIKeepAliveCount");

    duk_push_c_function(ctx, UI_DebugShowSettingsWindow, 1);
    duk_put_prop_string(ctx, -2, "debugShowSettingsWindow");

    duk_pop_2(ctx);

    js_class_get_prototype(ctx, "Atomic", "UIButton");
    duk_push_c_function(ctx, UIButton_Popup, 2);
    duk_put_prop_string(ctx, -2, "popup");
    duk_pop(ctx);

    js_class_get_prototype(ctx, "Atomic", "UIWindow");
    duk_push_c_function(ctx, UIWindow_GetResizeToFitContentRect, 0);
    duk_put_prop_string(ctx, -2, "getResizeToFitContentRect");
    duk_pop(ctx);


}
Пример #9
0
 void js_init_require(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
     duk_get_global_string(ctx, "Duktape");
     duk_push_c_function(ctx, js_module_search, 4);
     duk_put_prop_string(ctx, -2, "modSearch");
     duk_pop(ctx);
 }
Пример #10
0
Файл: vm.c Проект: cjihrig/sjs
static void sjs__setup_modsearch(sjs_vm_t* vm) {
    duk_context* ctx = vm->ctx;

    duk_get_global_string(ctx, "Duktape");
    duk_push_c_function(ctx, sjs__modsearch, 4 /* nargs */);
    duk_put_prop_string(ctx, -2, "modSearch");
    duk_pop(ctx);
}
Пример #11
0
static duk_int_t save_file(duk_context *ctx, const char *filename, const char *var) {
	duk_get_global_string(ctx, var);
	duk_size_t sz;
	char *buf = (char *)duk_get_buffer_data(ctx, -1, &sz);

	if(!buf) return 1;
	FILE *f = fopen(filename, "wb"); fwrite(buf, 1, sz, f); fclose(f);
	return 0;
}
void test(duk_context *ctx) {
	duk_bool_t ret;

	printf("top: %d\n", (int) duk_get_top(ctx));
	ret = duk_get_global_string(ctx, "encodeURIComponent");
	printf("top: %d\n", (int) duk_get_top(ctx));
	printf("ret: %d\n", ret);
	duk_push_string(ctx, "foo bar");
	duk_call(ctx, 1);
	printf("encoded: %s\n", duk_to_string(ctx, -1));
	duk_pop(ctx);
	printf("top: %d\n", (int) duk_get_top(ctx));

	ret = duk_get_global_string(ctx, "doesNotExist");
	printf("top: %d\n", (int) duk_get_top(ctx));
	printf("ret: %d\n", ret);
	printf("%s\n", duk_to_string(ctx, -1));
	duk_pop(ctx);
	printf("top: %d\n", (int) duk_get_top(ctx));
}
Пример #13
0
void Context::pushObject(void* ptr, const char* className)
{
  duk_push_object(m_handle);
  duk_push_pointer(m_handle, ptr);
  duk_put_prop_string(m_handle, -2, "\xFF" "\xFF" "ptr");

  duk_get_global_string(m_handle, className);
  duk_get_prop_string(m_handle, -1, "prototype");
  duk_set_prototype(m_handle, -3);
  duk_pop(m_handle);
}
Пример #14
0
void
_gum_duk_add_properties_to_class (duk_context * ctx,
                                  const gchar * class_name,
                                  const GumDukPropertyEntry * entries)
{
  duk_get_global_string (ctx, class_name);
  duk_get_prop_string (ctx, -1, "prototype");
  _gum_duk_add_properties_to_class_by_heapptr (ctx,
      duk_require_heapptr (ctx, -1), entries);
  duk_pop_2 (ctx);
}
Пример #15
0
void Context::pushThis(void* ptr, const char* className)
{
    duk_push_this(m_handle);
    duk_push_pointer(m_handle, ptr);
    duk_put_prop_string(m_handle, -2, kPtrId);

    // TODO classes in modules isn't supported yet
    duk_get_global_string(m_handle, className);
    duk_get_prototype(m_handle, -1);
    duk_set_prototype(m_handle, -3);
    duk_pop_2(m_handle);
}
Пример #16
0
Файл: vm.c Проект: joegen/sjs
static void sjs__setup_modsearch(sjs_vm_t* vm) {
    duk_context* ctx = vm->ctx;

    duk_get_global_string(ctx, "Duktape");
    duk_push_string(ctx, "modSearch");
    duk_push_c_function(ctx, sjs__modsearch, 4 /* nargs */);
    duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |
                          DUK_DEFPROP_CLEAR_WRITABLE |
                          DUK_DEFPROP_CLEAR_ENUMERABLE |
                          DUK_DEFPROP_CLEAR_CONFIGURABLE);
    duk_pop(ctx);
}
Пример #17
0
gboolean
_gum_duk_is_arg0_equal_to_prototype (duk_context * ctx,
                                     const gchar * class_name)
{
  gboolean result;

  duk_get_global_string (ctx, class_name);
  duk_get_prop_string (ctx, -1, "prototype");
  result = duk_equals (ctx, 0, -1);
  duk_pop_2 (ctx);

  return result;
}
Пример #18
0
bool StyleContext::evalStyleFn(const std::string& name, StyleParamKey _key, StyleParam::Value& _val) {
    if (!duk_get_global_string(m_ctx, name.c_str())) {
        logMsg("Error: evalFilter %s\n", name.c_str());
        return false;
    }

    if (duk_pcall(m_ctx, 0) != 0) {
        logMsg("Error: evalStyleFn: %s\n", duk_safe_to_string(m_ctx, -1));
        duk_pop(m_ctx);
        return false;
    }

    return parseStyleResult(_key, _val);
}
Пример #19
0
static void dukzip_push_unzfile(duk_context *ctx, unzFile archive, const char *filename) {
	/* create object with readable Dukzip archive prototype */
	duk_push_object(ctx);
	duk_get_global_string(ctx, DUKZIP_UNZ_PROTOTYPE);
	duk_set_prototype(ctx, -2);

	/* set the archive pointer data */
	duk_push_pointer(ctx, archive);
	duk_put_prop_string(ctx, -2, ZIPHANDLE_PROP);

	/* set path property */
	duk_push_string(ctx, filename);
	duk_put_prop_string(ctx, -2, ZIPFILENAME_PROP);
}
Пример #20
0
index_t Context::pushObject(void* ptr, const char* className)
{
    index_t obj = duk_push_object(m_handle);
    duk_push_pointer(m_handle, ptr);
    duk_put_prop_string(m_handle, obj, kPtrId);

    // TODO classes in modules isn't supported yet
    duk_get_global_string(m_handle, className);
    duk_get_prototype(m_handle, -1);
    duk_set_prototype(m_handle, obj);
    duk_pop(m_handle);

    return obj;
}
Пример #21
0
static void duknode_push_argv(duk_context *ctx, int argc, const char *argv[]) {
	duk_get_global_string(ctx, "process");

	duk_idx_t arg_array_index; int i;

	arg_array_index = duk_push_array(ctx);
	for (i = 0; i < argc; i++) {
		duk_push_string(ctx, argv[i]);
		duk_put_prop_index(ctx, arg_array_index, i);
	}

	duk_put_prop_string(ctx, -2, "argv");
	duk_pop(ctx);
}
Пример #22
0
static duk_ret_t test_basic(duk_context *ctx) {
	duk_bool_t ret;

	printf("top: %ld\n", (long) duk_get_top(ctx));
	ret = duk_get_global_string(ctx, "encodeURIComponent");
	printf("top: %ld\n", (long) duk_get_top(ctx));
	printf("ret: %ld\n", (long) ret);
	duk_push_string(ctx, "foo bar");
	duk_call(ctx, 1);
	printf("encoded: %s\n", duk_to_string(ctx, -1));
	duk_pop(ctx);
	printf("top: %ld\n", (long) duk_get_top(ctx));

	ret = duk_get_global_string(ctx, "doesNotExist");
	printf("top: %ld\n", (long) duk_get_top(ctx));
	printf("ret: %ld\n", (long) ret);
	printf("%s\n", duk_to_string(ctx, -1));
	duk_pop(ctx);
	printf("top: %ld\n", (long) duk_get_top(ctx));

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Пример #23
0
void jsapi_init_toolcore(JSVM* vm)
{
    duk_context* ctx = vm->GetJSContext();

    jsb_package_toolcore_init(vm);

    duk_get_global_string(ctx, "ToolCore");

    duk_push_c_function(ctx, js_atomic_GetToolEnvironment, 0);
    duk_put_prop_string(ctx, -2, "getToolEnvironment");

    js_push_class_object_instance(ctx, vm->GetSubsystem<ToolEnvironment>(), "ToolEnvironment");
    duk_put_prop_string(ctx, -2, "toolEnvironment");

    duk_push_c_function(ctx, js_atomic_GetToolSystem, 0);
    duk_put_prop_string(ctx, -2, "getToolSystem");

    js_push_class_object_instance(ctx, vm->GetSubsystem<ToolSystem>(), "ToolSystem");
    duk_put_prop_string(ctx, -2, "toolSystem");

    js_push_class_object_instance(ctx, vm->GetSubsystem<BuildSystem>(), "BuildSystem");
    duk_put_prop_string(ctx, -2, "buildSystem");

    duk_push_c_function(ctx, js_atomic_GetLicenseSystem, 0);
    duk_put_prop_string(ctx, -2, "getLicenseSystem");

    js_push_class_object_instance(ctx, vm->GetSubsystem<LicenseSystem>(), "LicenseSystem");
    duk_put_prop_string(ctx, -2, "licenseSystem");

    duk_push_c_function(ctx, js_atomic_GetAssetDatabase, 0);
    duk_put_prop_string(ctx, -2, "getAssetDatabase");

    js_push_class_object_instance(ctx, vm->GetSubsystem<AssetDatabase>(), "AssetDatabase");
    duk_put_prop_string(ctx, -2, "assetDatabase");

    duk_pop(ctx);

    js_class_get_prototype(ctx, "ToolCore", "AssetDatabase");
    duk_push_c_function(ctx, AssetDatabase_GetFolderAssets, 1);
    duk_put_prop_string(ctx, -2, "getFolderAssets");
    duk_push_c_function(ctx, AssetDatabase_GetAssetsByImporterType, 2);
    duk_put_prop_string(ctx, -2, "getAssetsByImporterType");
    duk_pop(ctx);

    js_class_get_prototype(ctx, "ToolCore", "ModelImporter");
    duk_push_c_function(ctx, ModelImporter_GetAnimations, 0);
    duk_put_prop_string(ctx, -2, "getAnimations");
    duk_pop(ctx);
}
static duk_ret_t test_1(duk_context *ctx, void *udata) {
	(void) udata;

	duk_eval_string(ctx,
		"new Proxy(this, {\n"
		"    get: function (targ, key, recv) { print('GET', key); if (key in targ) { return targ[key]; } else { return 'replaced'; } },\n"
		"    has: function (targ, key) { print('HAS', key); return true; }\n"
		"})");
	duk_set_global_object(ctx);

	duk_get_global_string(ctx, "Math");
	printf("%s\n", duk_safe_to_string(ctx, -1));
	duk_pop(ctx);

	duk_get_global_string(ctx, "nonExistent");
	printf("%s\n", duk_safe_to_string(ctx, -1));
	duk_pop(ctx);

	duk_eval_string_noresult(ctx, "print(typeof Math);");
	duk_eval_string_noresult(ctx, "print(typeof nonExistent);");

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
Пример #25
0
static void callJavascriptOverline(tic_mem* memory, void* data)
{
	tic_machine* machine = (tic_machine*)memory;
	duk_context* duk = machine->js;

	const char* OvrFunc = ApiKeywords[2];

	if(duk_get_global_string(duk, OvrFunc)) 
	{
		if(duk_pcall(duk, 0) != 0)
			machine->data->error(machine->data->data, duk_safe_to_string(duk, -1));
	}

	duk_pop(duk);
}
Пример #26
0
static void callJavascriptScanlineName(tic_mem* memory, s32 row, void* data, const char* name)
{
	tic_machine* machine = (tic_machine*)memory;
	duk_context* duk = machine->js;

	if(duk_get_global_string(duk, name)) 
	{
		duk_push_int(duk, row);

		if(duk_pcall(duk, 1) != 0)
			machine->data->error(machine->data->data, duk_safe_to_string(duk, -1));
	}

	duk_pop(duk);
}
Пример #27
0
void StyleContext::addAccessor(const std::string& _name) {

    auto it = m_accessors.find(_name);
    if (it != m_accessors.end()) {
        return;
    }

    auto entry = m_accessors.emplace(_name, Accessor{_name, this});
    if (!entry.second) {
        return; // hmm, already added..
    }

    Accessor& attr = (*entry.first).second;

    // push 'feature' obj onto stack
    if (!duk_get_global_string(m_ctx, "feature")) {
        logMsg("Error: 'feature' not in global scope\n");
        return;
    }

    // push property name
    duk_push_string(m_ctx, _name.c_str());

    // push getter function
    duk_push_c_function(m_ctx, jsPropertyGetter, 0 /*nargs*/);
    duk_push_pointer(m_ctx, (void*)&attr);
    duk_put_prop_string(m_ctx, -2, ATTR_ID);

    // push setter function
    // duk_push_c_function(m_ctx, jsPropertySetter, 1 /*nargs*/);
    // duk_push_pointer(m_ctx, (void*)&attr);
    // duk_put_prop_string(m_ctx, -2, ATTR_ID);

    // stack: [ feature_obj, name, getter, setter ] -> [ feature_obj.name ]
    duk_def_prop(m_ctx, -3,
                 DUK_DEFPROP_HAVE_GETTER |
                 // DUK_DEFPROP_HAVE_SETTER |
                 // DUK_DEFPROP_WRITABLE |
                 // DUK_DEFPROP_HAVE_ENUMERABLE |
                 // DUK_DEFPROP_ENUMERABLE |
                 // DUK_DEFPROP_HAVE_CONFIGURABLE |
                 0);

    // pop feature obj
    duk_pop(m_ctx);

    DUMP("addAccessor\n");
}
Пример #28
0
Engine::Engine(EngineDelegate* delegate)
    : m_ctx(duk_create_heap(&on_alloc_function,
                            &on_realloc_function,
                            &on_free_function,
                            (void*)this,
                            &on_fatal_handler))
    , m_delegate(delegate)
    , m_printLastResult(false)
{
    // Set 'on_search_module' as the function to search modules with
    // require('modulename') on JavaScript.
    duk_get_global_string(m_ctx.handle(), "Duktape");
    duk_push_c_function(m_ctx.handle(), &on_search_module, 4);
    duk_put_prop_string(m_ctx.handle(), -2, "modSearch");
    duk_pop(m_ctx.handle());
}
Пример #29
0
gpointer
_gum_duk_load_module_data (duk_context * ctx,
                           const gchar * module_id)
{
  gpointer result;
  guint8 key[32];

  key[0] = 0xff;
  g_strlcpy ((gchar *) (key + 1), module_id, sizeof (key) - 1);

  duk_get_global_string (ctx, (const gchar *) key);
  result = duk_get_pointer (ctx, -1);
  duk_pop (ctx);

  return result;
}
Пример #30
0
void jsapi_init_editor(JSVM* vm)
{
    duk_context* ctx = vm->GetJSContext();

    jsb_package_editor_init(vm);

    duk_get_global_string(ctx, "Atomic");

    if (vm->GetContext()->GetEditorContext()) {
        js_push_class_object_instance(ctx, vm->GetSubsystem<EditorMode>(), "EditorMode");
        duk_put_prop_string(ctx, -2, "editorMode");
    }

    duk_pop(ctx);

}