Example #1
0
	Handle<Value> CreateExternalArrayBuffer(int32_t length, uint8_t *data) {
	  Handle<Object> buffer = Object::New();
	  buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True());
	  Persistent<Object> persistent_array = Persistent<Object>::New(buffer);
	  persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
	  persistent_array.MarkIndependent();

	  buffer->SetIndexedPropertiesToExternalArrayData(
		  data, v8::kExternalByteArray, length);
	  buffer->Set(String::New("byteLength"), Int32::New(length), ReadOnly);
	  buffer->Set(String::New("address"), Int32::New(reinterpret_cast<uint32_t>(data)), ReadOnly);

	  return buffer;
	}
static gboolean
gum_script_event_sink_drain (gpointer user_data)
{
  GumScriptEventSink * self = GUM_SCRIPT_EVENT_SINK (user_data);
  gpointer buffer = NULL;
  guint len, size;

  if (self->core == NULL)
    return FALSE;

  len = self->queue->len;
  size = len * sizeof (GumEvent);
  if (len != 0)
  {
    buffer = g_memdup (self->queue->data, size);

    gum_spinlock_acquire (&self->lock);
    g_array_remove_range (self->queue, 0, len);
    gum_spinlock_release (&self->lock);
  }

  if (buffer != NULL)
  {
    GHashTable * frequencies = NULL;
    if (!self->on_call_summary.IsEmpty ())
    {
      frequencies = g_hash_table_new (NULL, NULL);
      GumCallEvent * ev = static_cast<GumCallEvent *> (buffer);
      for (guint i = 0; i != len; i++)
      {
        if (ev->type == GUM_CALL)
        {
          gsize count = GPOINTER_TO_SIZE (
              g_hash_table_lookup (frequencies, ev->target));
          count++;
          g_hash_table_insert (frequencies,
              ev->target, GSIZE_TO_POINTER (count));
        }

        ev++;
      }
    }

    ScriptScope scope (self->core->script);

    if (frequencies != NULL)
    {
      Handle<Object> summary = Object::New ();

      GHashTableIter iter;
      g_hash_table_iter_init (&iter, frequencies);
      gpointer target, count;
      while (g_hash_table_iter_next (&iter, &target, &count))
      {
        summary->Set (_gum_script_pointer_new (self->core, target),
            Number::New (GPOINTER_TO_SIZE (count)), ReadOnly);
      }

      g_hash_table_unref (frequencies);

      Handle<Value> argv[] = { summary };
      self->on_call_summary->Call (self->on_call_summary, 1, argv);
    }

    if (!self->on_receive.IsEmpty ())
    {
      V8::AdjustAmountOfExternalAllocatedMemory (size);

      Handle<Object> data = Object::New ();
      data->Set (String::New ("length"), Int32::New (size), ReadOnly);
      data->SetIndexedPropertiesToExternalArrayData (buffer,
          kExternalUnsignedByteArray, size);
      Persistent<Object> persistent_data = Persistent<Object>::New (data);
      persistent_data.MakeWeak (buffer, gum_script_event_sink_data_free);
      persistent_data.MarkIndependent ();

      Handle<Value> argv[] = { data };
      self->on_receive->Call (self->on_receive, 1, argv);
    }
    else
    {
      g_free (buffer);
    }
  }

  return TRUE;
}
Example #3
0
    Handle<Value> CreateExternalArray(const Arguments& args,
                                             ExternalArrayType type,
                                             size_t element_size) {
		TryCatch try_catch;
		ASSERT_PIN(element_size == 1 || element_size == 2 ||
			 element_size == 4 || element_size == 8, "CreateExternalArray");

		// Currently, only the following constructors are supported:
		//   TypedArray(unsigned long length)
		//   TypedArray(ArrayBuffer buffer,
		//              optional unsigned long byteOffset,
		//              optional unsigned long length)
		Handle<Object> buffer;
		int32_t length;
		int32_t byteLength;
		int32_t byteOffset;
		int32_t bufferLength;

		if (args.Length() == 0) {
		return ThrowException(
			String::New("Array constructor must have at least one parameter."));
		}

		if (args[0]->IsObject() &&
			(!args[0]->ToObject()->GetHiddenValue(String::New(kArrayBufferMarkerPropName)).IsEmpty()) ||
			(IS_BINARY(args[0]))) {
				if (!args[0]->ToObject()->GetHiddenValue(String::New(kArrayBufferMarkerPropName)).IsEmpty()) {
					buffer = args[0]->ToObject();
					bufferLength = convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
					if (try_catch.HasCaught())
						return try_catch.Exception();
				} else {
					buffer = CreateExternalArrayBuffer(args[0])->ToObject();
					bufferLength = convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
					if (try_catch.HasCaught())
						return try_catch.Exception();
				}

		if (args.Length() < 2 || args[1]->IsUndefined()) {
		  byteOffset = 0;
		} else {
		  byteOffset = convertToUint(args[1], &try_catch);
		  if (try_catch.HasCaught()) return try_catch.Exception();
		  if (byteOffset > bufferLength) {
			return ThrowException(String::New("byteOffset out of bounds"));
		  }
		  if (byteOffset % element_size != 0) {
			return ThrowException(
				String::New("byteOffset must be multiple of element_size"));
		  }
		}

		if (args.Length() < 3 || args[2]->IsUndefined()) {
		  byteLength = bufferLength - byteOffset;
		  length = byteLength / element_size;
		  if (byteLength % element_size != 0) {
			return ThrowException(
				String::New("buffer size must be multiple of element_size"));
		  }
		} else {
			  length = convertToUint(args[2], &try_catch);
			  if (try_catch.HasCaught())
				  return try_catch.Exception();
			  byteLength = length * element_size;
			  if (byteOffset + byteLength > bufferLength) {
				  return ThrowException(String::New("length out of bounds"));
			  }
		}
		} else {
			length = convertToUint(args[0], &try_catch);
			byteLength = length * element_size;
			byteOffset = 0;
			Handle<Value> result = CreateExternalArrayBuffer(byteLength);
			if (!result->IsObject())
				return result;
			buffer = result->ToObject();
		}

		void* data = buffer->GetIndexedPropertiesExternalArrayData();
		ASSERT_PIN(data != NULL, "CreateExternalArray data != NULL");

		Handle<Object> array = Object::New();
		array->SetIndexedPropertiesToExternalArrayData(
		  static_cast<uint8_t*>(data) + byteOffset, type, length);
		array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly);
		array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly);
		array->Set(String::New("length"), Int32::New(length), ReadOnly);
		array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
		array->Set(String::New("buffer"), buffer, ReadOnly);

		return array;
    }