forked from cory/tildefriends
		
	Fixed loads of memory leaks and related issues.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3782 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		@@ -78,7 +78,6 @@ function edit() {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	closeStats();
 | 
			
		||||
	gSplit = Split(['#editPane', '#viewPane'], {minSize: 0});
 | 
			
		||||
 | 
			
		||||
	ensureLoaded([
 | 
			
		||||
@@ -155,8 +154,6 @@ function trace() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function stats() {
 | 
			
		||||
	closeEditor();
 | 
			
		||||
	gSplit = Split(['#statsPane', '#viewPane'], {minSize: 0});
 | 
			
		||||
	document.getElementById("statsPane").style.display = 'flex';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,12 @@
 | 
			
		||||
			<span id="login"></span>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div id="content" class="hbox" style="flex: 1 1; width: 100%">
 | 
			
		||||
			<div id="statsPane" class="vbox" style="display: none; flex 1 0 320px">
 | 
			
		||||
				<div class="hbox">
 | 
			
		||||
					<input type="button" id="closeStats" name="closeStats" value="Close" onclick="closeStats()">
 | 
			
		||||
				</div>
 | 
			
		||||
				<div id="graphs"></div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div id="editPane" class="vbox" style="display: none">
 | 
			
		||||
				<div class="navigation">
 | 
			
		||||
					<input type="button" id="closeEditor" name="closeEditor" value="Close" onclick="closeEditor()">
 | 
			
		||||
@@ -43,12 +49,6 @@
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div id="statsPane" class="vbox" style="display: none">
 | 
			
		||||
				<div class="hbox">
 | 
			
		||||
					<input type="button" id="closeStats" name="closeStats" value="Close" onclick="closeStats()">
 | 
			
		||||
				</div>
 | 
			
		||||
				<div id="graphs"></div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div id="viewPane" class="vbox" style="flex: 1 0 50%; overflow: auto">
 | 
			
		||||
				<iframe id="document" sandbox="allow-forms allow-scripts allow-top-navigation allow-modals" style="width: 100%; height: 100%; border: 0"></iframe>
 | 
			
		||||
			</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -270,6 +270,8 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_
 | 
			
		||||
			if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1)
 | 
			
		||||
			{
 | 
			
		||||
				key_value = desc.value;
 | 
			
		||||
				JS_FreeValue(tf_task_get_context(task), desc.setter);
 | 
			
		||||
				JS_FreeValue(tf_task_get_context(task), desc.getter);
 | 
			
		||||
			}
 | 
			
		||||
			_serialize_storeInternal(task, to, buffer, key, depth + 1);
 | 
			
		||||
			_serialize_storeInternal(task, to, buffer, key_value, depth + 1);
 | 
			
		||||
@@ -297,6 +299,8 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_
 | 
			
		||||
			if (JS_GetOwnProperty(tf_task_get_context(task), &desc, value, ptab[i].atom) == 1)
 | 
			
		||||
			{
 | 
			
		||||
				key_value = desc.value;
 | 
			
		||||
				JS_FreeValue(tf_task_get_context(task), desc.setter);
 | 
			
		||||
				JS_FreeValue(tf_task_get_context(task), desc.getter);
 | 
			
		||||
			}
 | 
			
		||||
			_serialize_storeInternal(task, to, buffer, key, depth + 1);
 | 
			
		||||
			_serialize_storeInternal(task, to, buffer, key_value, depth + 1);
 | 
			
		||||
@@ -325,7 +329,7 @@ static JSValue _serialize_load(tf_task_t* task, tf_taskstub_t* from, const char*
 | 
			
		||||
 | 
			
		||||
static JSValue _serialize_loadInternal(tf_task_t* task, tf_taskstub_t* from, const char** buffer, size_t* size, int depth)
 | 
			
		||||
{
 | 
			
		||||
	if (*size < sizeof(size))
 | 
			
		||||
	if (*size < sizeof(int32_t))
 | 
			
		||||
	{
 | 
			
		||||
		return JS_UNDEFINED;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -112,6 +112,8 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key)
 | 
			
		||||
				JS_FreeValue(context, key);
 | 
			
		||||
				JS_FreeCString(context, blob_id);
 | 
			
		||||
				JS_FreeValue(context, desc.value);
 | 
			
		||||
				JS_FreeValue(context, desc.setter);
 | 
			
		||||
				JS_FreeValue(context, desc.getter);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								src/task.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/task.c
									
									
									
									
									
								
							@@ -208,15 +208,17 @@ static import_record_t** _tf_task_find_import(tf_task_t* task, taskid_t task_id,
 | 
			
		||||
 | 
			
		||||
static bool _import_record_release(import_record_t** import)
 | 
			
		||||
{
 | 
			
		||||
	JSContext* context = (*import)->_owner->_context;
 | 
			
		||||
	tf_task_t* task = (*import)->_owner;
 | 
			
		||||
	import_record_t* record = *import;
 | 
			
		||||
 | 
			
		||||
	if (--record->_useCount == 0)
 | 
			
		||||
	{
 | 
			
		||||
		JS_SetOpaque(record->_function, NULL);
 | 
			
		||||
		JS_FreeValue(context, record->_function);
 | 
			
		||||
		record->_function = JS_UNDEFINED;
 | 
			
		||||
		tf_task_t* task = record->_owner;
 | 
			
		||||
		JSContext* context = task->_context;
 | 
			
		||||
		if (!JS_IsUndefined(record->_function))
 | 
			
		||||
		{
 | 
			
		||||
			JS_SetOpaque(record->_function, NULL);
 | 
			
		||||
			JS_FreeValue(context, record->_function);
 | 
			
		||||
			record->_function = JS_UNDEFINED;
 | 
			
		||||
		}
 | 
			
		||||
		_tf_task_release_export(_tf_task_get_stub(task, record->_task), record->_export);
 | 
			
		||||
 | 
			
		||||
		int index = import - task->_imports;
 | 
			
		||||
@@ -427,6 +429,7 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid
 | 
			
		||||
	if (export)
 | 
			
		||||
	{
 | 
			
		||||
		JSValue arguments = tf_serialize_load(to, from, buffer, size);
 | 
			
		||||
 | 
			
		||||
		JSValue* argument_array = NULL;
 | 
			
		||||
		JSValue length_val = JS_GetPropertyStr(to->_context, arguments, "length");
 | 
			
		||||
		int length;
 | 
			
		||||
@@ -443,14 +446,18 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid
 | 
			
		||||
				argument_array[i - 1] = JS_GetPropertyUint32(to->_context, arguments, i);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		JS_FreeValue(to->_context, length_val);
 | 
			
		||||
		JSValue function = export->_function;
 | 
			
		||||
		JSPropertyDescriptor desc;
 | 
			
		||||
 | 
			
		||||
		JSPropertyDescriptor desc = { 0 };
 | 
			
		||||
		const char* name = NULL;
 | 
			
		||||
		JSAtom atom = JS_NewAtom(to->_context, "name");
 | 
			
		||||
		if (JS_GetOwnProperty(to->_context, &desc, function, atom) == 1)
 | 
			
		||||
		{
 | 
			
		||||
			name = JS_ToCString(to->_context, desc.value);
 | 
			
		||||
			JS_FreeValue(to->_context, desc.value);
 | 
			
		||||
			JS_FreeValue(to->_context, desc.setter);
 | 
			
		||||
			JS_FreeValue(to->_context, desc.getter);
 | 
			
		||||
		}
 | 
			
		||||
		JS_FreeAtom(to->_context, atom);
 | 
			
		||||
		tf_trace_begin(to->_trace, name ? name : "_task_invokeExport_internal");
 | 
			
		||||
@@ -458,10 +465,18 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid
 | 
			
		||||
		{
 | 
			
		||||
			JS_FreeCString(to->_context, name);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		result = JS_Call(to->_context, function, this_val, length - 1, argument_array);
 | 
			
		||||
		tf_trace_end(to->_trace);
 | 
			
		||||
		tf_util_report_error(to->_context, result);
 | 
			
		||||
		tf_task_run_jobs(to);
 | 
			
		||||
 | 
			
		||||
		JS_FreeValue(to->_context, this_val);
 | 
			
		||||
		for (int i = 0; i < length - 1; i++)
 | 
			
		||||
		{
 | 
			
		||||
			JS_FreeValue(to->_context, argument_array[i]);
 | 
			
		||||
		}
 | 
			
		||||
		JS_FreeValue(to->_context, arguments);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
@@ -498,7 +513,8 @@ static JSValue _invokeCatch(JSContext* context, JSValueConst this_val, int argc,
 | 
			
		||||
static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result)
 | 
			
		||||
{
 | 
			
		||||
	// We're not going to serialize/deserialize a promise...
 | 
			
		||||
	JSValue data[] = {
 | 
			
		||||
	JSValue data[] =
 | 
			
		||||
	{
 | 
			
		||||
		JS_NewInt32(from->_context, tf_taskstub_get_id(to)),
 | 
			
		||||
		JS_NewInt32(from->_context, promise),
 | 
			
		||||
	};
 | 
			
		||||
@@ -515,6 +531,11 @@ static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t pro
 | 
			
		||||
	tf_util_report_error(from->_context, error);
 | 
			
		||||
	JS_FreeValue(from->_context, error);
 | 
			
		||||
 | 
			
		||||
	JS_FreeValue(from->_context, promise_then);
 | 
			
		||||
	JS_FreeValue(from->_context, promise_catch);
 | 
			
		||||
	JS_FreeValue(from->_context, then_handler);
 | 
			
		||||
	JS_FreeValue(from->_context, catch_handler);
 | 
			
		||||
 | 
			
		||||
	tf_task_run_jobs(from);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -531,6 +552,7 @@ static void _tf_task_sendPromiseResolve(tf_task_t* from, tf_taskstub_t* to, prom
 | 
			
		||||
	{
 | 
			
		||||
		_tf_task_sendPromiseMessage(from, to, kResolvePromise, promise, result);
 | 
			
		||||
	}
 | 
			
		||||
	JS_FreeValue(from->_context, promiseType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _tf_task_sendPromiseReject(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result)
 | 
			
		||||
@@ -546,6 +568,7 @@ static void _tf_task_sendPromiseReject(tf_task_t* from, tf_taskstub_t* to, promi
 | 
			
		||||
	{
 | 
			
		||||
		_tf_task_sendPromiseMessage(from, to, kRejectPromise, promise, result);
 | 
			
		||||
	}
 | 
			
		||||
	JS_FreeValue(from->_context, promiseType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _tf_task_sendPromiseMessage(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t messageType, promiseid_t promise, JSValue result)
 | 
			
		||||
@@ -749,7 +772,7 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length,
 | 
			
		||||
			memcpy(&promise, begin, sizeof(promise));
 | 
			
		||||
			memcpy(&exportId, begin + sizeof(promise), sizeof(exportId));
 | 
			
		||||
 | 
			
		||||
			JSValue result = _task_invokeExport_internal(from, to, exportId, begin + sizeof(promiseid_t) + sizeof(exportid_t), length);
 | 
			
		||||
			JSValue result = _task_invokeExport_internal(from, to, exportId, begin + sizeof(promiseid_t) + sizeof(exportid_t), length - sizeof(promiseid_t) - sizeof(exportid_t));
 | 
			
		||||
			if (JS_IsException(result))
 | 
			
		||||
			{
 | 
			
		||||
				_tf_task_sendPromiseReject(to, from, promise, result);
 | 
			
		||||
@@ -869,6 +892,8 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length,
 | 
			
		||||
				if (JS_GetOwnProperty(to->_context, &desc, imports, ptab[i].atom) == 1)
 | 
			
		||||
				{
 | 
			
		||||
					JS_SetProperty(to->_context, global, ptab[i].atom, desc.value);
 | 
			
		||||
					JS_FreeValue(to->_context, desc.setter);
 | 
			
		||||
					JS_FreeValue(to->_context, desc.getter);
 | 
			
		||||
				}
 | 
			
		||||
				JS_FreeAtom(to->_context, ptab[i].atom);
 | 
			
		||||
			}
 | 
			
		||||
@@ -1240,6 +1265,7 @@ static void _import_finalizer(JSRuntime* runtime, JSValue value)
 | 
			
		||||
	import_record_t* import = JS_GetOpaque(value, _import_class_id);
 | 
			
		||||
	if (import)
 | 
			
		||||
	{
 | 
			
		||||
		import->_function = JS_UNDEFINED;
 | 
			
		||||
		import_record_t** it = _tf_task_find_import(import->_owner, import->_task, import->_export);
 | 
			
		||||
		_import_record_release(it);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1526,12 +1552,19 @@ void tf_task_destroy(tf_task_t* task)
 | 
			
		||||
 | 
			
		||||
JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_id)
 | 
			
		||||
{
 | 
			
		||||
	import_record_t** it = _tf_task_find_import(task, stub_id, export_id);
 | 
			
		||||
	if (it)
 | 
			
		||||
	{
 | 
			
		||||
		(*it)->_useCount++;
 | 
			
		||||
		return JS_DupValue(task->_context, (*it)->_function);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	JSValue function = JS_NewObjectClass(task->_context, _import_class_id);
 | 
			
		||||
	import_record_t* import = malloc(sizeof(import_record_t));
 | 
			
		||||
	JS_SetOpaque(function, import);
 | 
			
		||||
	*import = (import_record_t)
 | 
			
		||||
	{
 | 
			
		||||
		._function = JS_DupValue(task->_context, function),
 | 
			
		||||
		._function = function,
 | 
			
		||||
		._export = export_id,
 | 
			
		||||
		._owner = task,
 | 
			
		||||
		._task = stub_id,
 | 
			
		||||
@@ -1546,7 +1579,7 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_
 | 
			
		||||
	}
 | 
			
		||||
	task->_imports[index] = import;
 | 
			
		||||
	task->_import_count++;
 | 
			
		||||
	return function;
 | 
			
		||||
	return JS_DupValue(task->_context, function);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tf_task_t* tf_task_get(JSContext* context)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user