2010-12-06 03:21:09 +00:00
|
|
|
/* Copyright (c) 2008-2010, Avian Contributors
|
2008-02-19 18:06:52 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2007-07-06 23:50:26 +00:00
|
|
|
#include "machine.h"
|
2007-07-24 01:44:20 +00:00
|
|
|
#include "constants.h"
|
2007-09-24 01:39:03 +00:00
|
|
|
#include "processor.h"
|
2009-08-10 13:56:16 +00:00
|
|
|
#include "util.h"
|
2007-07-06 15:24:06 +00:00
|
|
|
|
2007-07-24 01:44:20 +00:00
|
|
|
using namespace vm;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
int64_t
|
2010-09-14 16:49:41 +00:00
|
|
|
search(Thread* t, object loader, object name,
|
|
|
|
object (*op)(Thread*, object, object), bool replaceDots)
|
2007-07-07 23:47:35 +00:00
|
|
|
{
|
2007-09-18 23:30:09 +00:00
|
|
|
if (LIKELY(name)) {
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, loader);
|
2009-06-11 23:13:25 +00:00
|
|
|
PROTECT(t, name);
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
object n = makeByteArray(t, stringLength(t, name) + 1);
|
2007-09-18 23:30:09 +00:00
|
|
|
char* s = reinterpret_cast<char*>(&byteArrayBody(t, n, 0));
|
2009-05-26 02:02:25 +00:00
|
|
|
stringChars(t, name, s);
|
2007-09-18 23:30:09 +00:00
|
|
|
|
|
|
|
if (replaceDots) {
|
|
|
|
replace('.', '/', s);
|
|
|
|
}
|
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
object r = op(t, loader, n);
|
2007-09-18 23:30:09 +00:00
|
|
|
if (t->exception) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
return reinterpret_cast<int64_t>(r);
|
2007-09-18 23:30:09 +00:00
|
|
|
} else {
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
|
2007-09-18 23:30:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
object
|
|
|
|
resolveSystemClassThrow(Thread* t, object loader, object spec)
|
2010-09-01 16:13:52 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
return resolveSystemClass(t, loader, spec, true);
|
2010-09-01 16:13:52 +00:00
|
|
|
}
|
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
} // namespace
|
2007-08-10 23:45:47 +00:00
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2010-09-01 16:13:52 +00:00
|
|
|
Avian_avian_SystemClassLoader_findLoadedVMClass
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-07-24 01:44:20 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
2007-07-24 01:44:20 +00:00
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
return search(t, loader, name, findLoadedClass, true);
|
2007-07-30 23:19:05 +00:00
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2010-09-01 16:13:52 +00:00
|
|
|
Avian_avian_SystemClassLoader_findVMClass
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2009-12-25 00:58:48 +00:00
|
|
|
{
|
|
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
2010-09-14 16:49:41 +00:00
|
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
2009-12-25 00:58:48 +00:00
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
return search(t, loader, name, resolveSystemClassThrow, true);
|
2009-12-25 00:58:48 +00:00
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2009-05-26 03:36:29 +00:00
|
|
|
Avian_avian_SystemClassLoader_resourceExists
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-07-30 23:19:05 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
object loader = reinterpret_cast<object>(arguments[0]);
|
|
|
|
object name = reinterpret_cast<object>(arguments[1]);
|
2007-09-18 23:30:09 +00:00
|
|
|
|
2007-08-10 23:45:47 +00:00
|
|
|
if (LIKELY(name)) {
|
2009-08-27 00:26:44 +00:00
|
|
|
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
|
|
|
|
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
2010-09-17 01:43:27 +00:00
|
|
|
|
2010-11-05 19:18:28 +00:00
|
|
|
unsigned length;
|
|
|
|
bool r = static_cast<Finder*>(systemClassLoaderFinder(t, loader))->stat
|
|
|
|
(RUNTIME_ARRAY_BODY(n), &length) == System::TypeFile;
|
2010-09-17 01:43:27 +00:00
|
|
|
|
2010-09-17 22:11:04 +00:00
|
|
|
// fprintf(stderr, "resource %s exists? %d\n", n, r);
|
2010-09-17 01:43:27 +00:00
|
|
|
|
|
|
|
return r;
|
2007-08-10 23:45:47 +00:00
|
|
|
} else {
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
|
2007-08-10 23:45:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2007-07-30 23:19:05 +00:00
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2010-09-14 16:49:41 +00:00
|
|
|
Avian_avian_SystemClassLoader_getClass
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-08-01 23:48:36 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
return reinterpret_cast<int64_t>
|
|
|
|
(getJClass(t, reinterpret_cast<object>(arguments[0])));
|
2007-07-24 01:44:20 +00:00
|
|
|
}
|
|
|
|
|
2008-11-11 15:20:49 +00:00
|
|
|
#ifdef AVIAN_HEAPDUMP
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-05-26 03:36:29 +00:00
|
|
|
Avian_avian_Machine_dumpHeap
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2008-11-11 15:20:49 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
object outputFile = reinterpret_cast<object>(*arguments);
|
2008-11-11 15:20:49 +00:00
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
unsigned length = stringLength(t, outputFile);
|
2008-11-11 15:20:49 +00:00
|
|
|
char n[length + 1];
|
2009-05-26 02:02:25 +00:00
|
|
|
stringChars(t, outputFile, n);
|
2009-09-01 18:15:33 +00:00
|
|
|
FILE* out = vm::fopen(n, "wb");
|
2008-11-11 15:20:49 +00:00
|
|
|
if (out) {
|
|
|
|
{ ENTER(t, Thread::ExclusiveState);
|
|
|
|
dumpHeap(t, out);
|
|
|
|
}
|
|
|
|
fclose(out);
|
|
|
|
} else {
|
|
|
|
object message = makeString(t, "file not found: %s", n);
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
t->exception = makeThrowable(t, Machine::RuntimeExceptionType, message);
|
2008-11-11 15:20:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif//AVIAN_HEAPDUMP
|
|
|
|
|
2007-09-18 23:30:09 +00:00
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-05-26 02:02:25 +00:00
|
|
|
Avian_java_lang_Runtime_exit
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-07-21 17:50:26 +00:00
|
|
|
{
|
2009-08-19 20:27:03 +00:00
|
|
|
shutDown(t);
|
|
|
|
|
2009-09-18 00:28:42 +00:00
|
|
|
t->m->system->exit(arguments[1]);
|
2007-07-21 17:50:26 +00:00
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2009-06-07 02:32:44 +00:00
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2008-07-15 15:36:52 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
object path = reinterpret_cast<object>(*arguments);
|
2008-07-15 15:36:52 +00:00
|
|
|
|
|
|
|
if (LIKELY(path)) {
|
2009-08-27 00:26:44 +00:00
|
|
|
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
|
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
2008-07-15 15:36:52 +00:00
|
|
|
|
2010-09-17 01:43:27 +00:00
|
|
|
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
|
|
|
|
if (r == 0) {
|
|
|
|
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
|
|
|
|
}
|
|
|
|
|
2008-07-15 15:36:52 +00:00
|
|
|
if (r) {
|
|
|
|
jint rSize = r->length();
|
|
|
|
r->dispose();
|
|
|
|
return rSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2009-06-07 02:32:44 +00:00
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_open
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-08-10 23:45:47 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
object path = reinterpret_cast<object>(*arguments);
|
2007-09-18 23:30:09 +00:00
|
|
|
|
2007-08-10 23:45:47 +00:00
|
|
|
if (LIKELY(path)) {
|
2009-08-27 00:26:44 +00:00
|
|
|
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
|
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
2007-08-10 23:45:47 +00:00
|
|
|
|
2010-09-17 01:43:27 +00:00
|
|
|
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
|
|
|
|
if (r == 0) {
|
|
|
|
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
|
|
|
|
}
|
|
|
|
|
|
|
|
return reinterpret_cast<int64_t>(r);
|
2007-08-10 23:45:47 +00:00
|
|
|
} else {
|
avoid inifinite recursion if java.lang.Object is missing; refactoring
When trying to create an array class, we try to resolve
java.lang.Object so we can use its vtable in the array class.
However, if Object is missing, we'll try to create and throw a
ClassNotFoundException, which requires creating an array to store the
stack trace, which requires creating an array class, which requires
resolving Object, etc.. This commit short-circuits this process by
telling resolveClass not to create and throw an exception if it can't
find Object.
While doing the above work, I noticed that the implementations of
Classpath::makeThrowable in classpath-avian.cpp and
classpath-openjdk.cpp were identical, so I made makeThrowable a
top-level function.
Finally, I discovered that Thread.setDaemon can only be called before
the target thread has been started, which allowed me to simplify the
code to track daemon threads in the VM.
2010-12-10 02:38:12 +00:00
|
|
|
t->exception = makeThrowable(t, Machine::NullPointerExceptionType);
|
2007-08-10 23:45:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-17 22:11:04 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_available
|
|
|
|
(Thread*, object, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
|
|
int32_t position = arguments[2];
|
|
|
|
|
|
|
|
System::Region* region = reinterpret_cast<System::Region*>(peer);
|
|
|
|
return static_cast<jint>(region->length()) - position;
|
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2009-06-07 02:32:44 +00:00
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_read__JI
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread*, object, uintptr_t* arguments)
|
2007-08-10 23:45:47 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
|
|
int32_t position = arguments[2];
|
|
|
|
|
2007-09-17 00:13:36 +00:00
|
|
|
System::Region* region = reinterpret_cast<System::Region*>(peer);
|
|
|
|
if (position >= static_cast<jint>(region->length())) {
|
2007-08-10 23:45:47 +00:00
|
|
|
return -1;
|
|
|
|
} else {
|
2007-09-17 00:13:36 +00:00
|
|
|
return region->start()[position];
|
2007-08-10 23:45:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 02:02:25 +00:00
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
2009-06-07 02:32:44 +00:00
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_read__JI_3BII
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2007-08-10 23:45:47 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
|
|
|
int32_t position = arguments[2];
|
|
|
|
object buffer = reinterpret_cast<object>(arguments[3]);
|
|
|
|
int32_t offset = arguments[4];
|
|
|
|
int32_t length = arguments[5];
|
2007-09-18 23:30:09 +00:00
|
|
|
|
2007-09-13 00:21:37 +00:00
|
|
|
if (length == 0) return 0;
|
|
|
|
|
2007-09-17 00:13:36 +00:00
|
|
|
System::Region* region = reinterpret_cast<System::Region*>(peer);
|
|
|
|
if (length > static_cast<jint>(region->length()) - position) {
|
|
|
|
length = static_cast<jint>(region->length()) - position;
|
2007-08-10 23:45:47 +00:00
|
|
|
}
|
2007-09-13 00:21:37 +00:00
|
|
|
if (length <= 0) {
|
2007-08-10 23:45:47 +00:00
|
|
|
return -1;
|
|
|
|
} else {
|
2009-05-26 02:02:25 +00:00
|
|
|
memcpy(&byteArrayBody(t, buffer, offset), region->start() + position,
|
|
|
|
length);
|
2007-08-10 23:45:47 +00:00
|
|
|
return length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-09-18 23:30:09 +00:00
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-06-07 02:32:44 +00:00
|
|
|
Avian_avian_resource_Handler_00024ResourceInputStream_close
|
2009-05-26 02:02:25 +00:00
|
|
|
(Thread*, object, uintptr_t* arguments)
|
2007-08-10 23:45:47 +00:00
|
|
|
{
|
2009-05-26 02:02:25 +00:00
|
|
|
int64_t peer; memcpy(&peer, arguments, 8);
|
2007-09-17 00:13:36 +00:00
|
|
|
reinterpret_cast<System::Region*>(peer)->dispose();
|
2007-08-10 23:45:47 +00:00
|
|
|
}
|
2009-05-06 00:29:05 +00:00
|
|
|
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-05-23 22:15:06 +00:00
|
|
|
Avian_avian_Continuations_callWithCurrentContinuation
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2009-05-06 00:29:05 +00:00
|
|
|
{
|
|
|
|
t->m->processor->callWithCurrentContinuation
|
|
|
|
(t, reinterpret_cast<object>(*arguments));
|
|
|
|
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
|
2009-05-23 22:15:06 +00:00
|
|
|
extern "C" JNIEXPORT void JNICALL
|
|
|
|
Avian_avian_Continuations_dynamicWind2
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
t->m->processor->dynamicWind
|
|
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
|
|
reinterpret_cast<object>(arguments[1]),
|
|
|
|
reinterpret_cast<object>(arguments[2]));
|
|
|
|
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
|
2009-05-06 00:29:05 +00:00
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-05-16 08:03:03 +00:00
|
|
|
Avian_avian_Continuations_00024Continuation_handleResult
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2009-05-06 00:29:05 +00:00
|
|
|
{
|
|
|
|
t->m->processor->feedResultToContinuation
|
|
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
|
|
reinterpret_cast<object>(arguments[1]));
|
|
|
|
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT void JNICALL
|
2009-05-16 08:03:03 +00:00
|
|
|
Avian_avian_Continuations_00024Continuation_handleException
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
2009-05-06 00:29:05 +00:00
|
|
|
{
|
|
|
|
t->m->processor->feedExceptionToContinuation
|
|
|
|
(t, reinterpret_cast<object>(arguments[0]),
|
|
|
|
reinterpret_cast<object>(arguments[1]));
|
|
|
|
|
|
|
|
abort(t);
|
|
|
|
}
|
2009-09-19 22:21:15 +00:00
|
|
|
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
|
|
Avian_avian_Singleton_getObject
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<int64_t>
|
|
|
|
(singletonObject(t, reinterpret_cast<object>(arguments[0]), arguments[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
|
|
Avian_avian_Singleton_getInt
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
return singletonValue
|
|
|
|
(t, reinterpret_cast<object>(arguments[0]), arguments[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT int64_t JNICALL
|
|
|
|
Avian_avian_Singleton_getLong
|
|
|
|
(Thread* t, object, uintptr_t* arguments)
|
|
|
|
{
|
|
|
|
int64_t v;
|
2009-10-20 19:38:05 +00:00
|
|
|
memcpy(&v, &singletonValue
|
|
|
|
(t, reinterpret_cast<object>(arguments[0]), arguments[1]), 8);
|
2009-09-19 22:21:15 +00:00
|
|
|
return v;
|
|
|
|
}
|