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 }
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; }
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; }
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); }
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 */ }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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; }
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); }
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); }
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; }
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); }
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; }
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; }
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); }
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); }
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"); }
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()); }
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; }
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); }